example - Java-HashSet es la mejor manera de implementar el iterador que no admite eliminar()
set hashset (5)
Crear el contenedor utilizando una clase interna anónima es bastante simple:
Mira este ejemplo:
package some;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
class MyIterable<E> implements Iterable<E> {
private Set<E> internalSet = new HashSet<E>();
public MyIterable( E ... all ) {
for( E e : all ){
internalSet.add( e );
}
}
public Iterator<E> iterator() {
final Iterator<E> i = internalSet.iterator();
return new Iterator<E>() {
public boolean hasNext(){
return i.hasNext();
}
public E next(){
return i.next();
}
public void remove(){
//you may throw new UnsupportedOperationException();
}
};
}
// Test it
public static void main( String [] args ) {
Iterable<String> iterable = new MyIterable<String>("a", "b", "a", "b");
System.out.println("Trying to invoke: remove");
for(Iterator<String> iterator = iterable.iterator();
iterator.hasNext();
iterator.remove() ){
System.out.println(iterator.next());
}
System.out.println("Used in foreach");
for( String s : iterable ){
System.out.println( s );
}
}
}
También puede lanzar UnsupportedOperationException
si desea declarar explícitamente que la operación no es compatible, pero puede ser un poco excesiva.
Tengo una clase que usa un HashSet
y quiero que la clase implemente Iterable
; sin embargo, no quiero que el iterador de clase admita el método remove()
.
El iterador predeterminado de HashSet
es HashSet.KeyIterator
que es una clase privada dentro de la clase HashSet
, por lo que no puedo extenderlo y anular el método de eliminación.
Idealmente, me gustaría evitar escribir una clase contenedora para KeyIterator
, pero no entiendo de qué otra manera podría implementar mi propio iterador de otra manera.
¿Algunas ideas?
Aclamaciones,
Pete
Si está utilizando colecciones de Apache Commons, puede usar org.apache.commons.collections.iterators.UnmodifiableIterator :
UnmodifiableIterator.decorate(set.iterator());
Guava (Google Collections) también tiene un Identificador no modificable, que admite genéricos: com.google.common.collect.UnmodifiableIterator<E>
Uso:
Iterators.unmodifiableIterator(set.iterator());
Utilice el patrón Compuesto : cree una nueva implementación de la interfaz del Iterator
que es un contenedor alrededor del iterador desde el HashSet
, pero en lugar de pasar llamadas para remove
arroje una UnsupportedOperationException
.
java.util.Collections.unmodifiableSet(myHashSet).iterator();
A continuación se muestra una forma de evitar este tipo de excepciones al eliminar elementos del iterador
List<String> results=new ArrayList<String>() //a collection
Iterator<String> itr=results.iterator();
List<String> toBeRemoved=new ArrayList<String>();
while(itr.hasNext()){
if(condiation){
tobeRemoved.add(itr.next);
}
}
//now we can remove unnecessary elements form the iterator
results.removeAll(toBeRemoved);
Este tipo de implementaciones es garantía de que no hay excepciones en la modificación del iterador