Java - HashSet实现不支持remove()的迭代器的最佳方法

时间:2010-06-18 17:53:04

标签: java collections iterator

我有一个使用HashSet的类,我想要类实现Iterable,但我不希望类迭代器支持remove()方法。

HashSet的默认迭代器是HashSet.KeyIterator,它是HashSet类中的私有类,所以我不能简单地扩展它并覆盖remove方法。

理想情况下,我想避免为KeyIterator编写包装类,但我不知道如何轻松地以其他任何方式简单地实现我自己的迭代器。

有什么想法吗?

干杯,

皮特

5 个答案:

答案 0 :(得分:16)

java.util.Collections.unmodifiableSet(myHashSet).iterator();

答案 1 :(得分:1)

如果您使用的是Apache Commons Collections,则可以使用org.apache.commons.collections.iterators.UnmodifiableIterator

UnmodifiableIterator.decorate(set.iterator());

Guava(Google Collections)还有一个UnmodifiableIterator,它支持泛型:com.google.common.collect.UnmodifiableIterator<E>用法:

Iterators.unmodifiableIterator(set.iterator());

答案 2 :(得分:1)

下面是一种从迭代器中删除元素时可以避免这种异常的方法

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

这种实现保证在修改迭代器时没有异常

答案 3 :(得分:0)

使用Composite pattern:创建Iterator接口的新实现,该接口是来自HashSet的迭代器的包装器,而不是通过调用remove扔一个UnsupportedOperationException

答案 4 :(得分:0)

使用匿名内部类创建包装器非常简单:

见这个例子:

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

    }
}

如果您想明确声明不支持该操作,您也可以抛出UnsupportedOperationException,但这可能有点过分。