Java - HashSet is the best way to implement an iterator that does not support remove ()

I have a class that uses a HashSet , and I want to implement the Iterable class, but I don't want the class iterator to support the remove() method.

The default HashSet iterator is HashSet.KeyIterator , which is a private class in the HashSet class, so I cannot just extend it and override the remove method.

Ideally, I would like to avoid writing a wrapper class for KeyIterator , but I don't understand how else I could easily and simply implement my own iterator in any other way.

Any ideas?

Greetings

Pete

+6
java iterator collections
source share
5 answers
 java.util.Collections.unmodifiableSet(myHashSet).iterator(); 
+16
source share

If you use the Apache Commons collection, you can use org.apache.commons.collections.iterators.UnmodifiableIterator :

 UnmodifiableIterator.decorate(set.iterator()); 

Guava (Google Collections) also has a UnmodifiableIterator that supports generics: com.google.common.collect.UnmodifiableIterator<E> Usage:

 Iterators.unmodifiableIterator(set.iterator()); 
+1
source share

The following is one way to avoid such exceptions when deleting items from an iterator

 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); 

This type of implementation ensures that exceptions when modifying an iterator

+1
source share

Creating a wrapper using an anonymous inner class is pretty simple:

See this example:

 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 ); } } } 

You can also throw an UnsupportedOperationException if you want to explicitly declare that the operation is not supported, but may be a bit excessive.

0
source share

Use the Composite pattern : create a new implementation of the Iterator interface, which is a wrapper around the iterator from the HashSet , but instead of passing through calls to remove UnsupportedOperationException .

-one
source share

All Articles