有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

HashSet的默认迭代器是HashSet.KeyIterator,它是HashSet类中的私有类,因此我不能简单地扩展它并重写remove方法

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

有什么想法吗

干杯

皮特


共 (5) 个答案

  1. # 1 楼答案

    java.util.Collections.unmodifiableSet(myHashSet).iterator();
    
  2. # 2 楼答案

    下面是在从迭代器中删除元素时避免此类异常的一种方法

    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. # 3 楼答案

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

  4. # 4 楼答案

    使用匿名内部类创建包装器相当简单:

    请参见此示例:

    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,但这可能有点过分

  5. # 5 楼答案

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

    UnmodifiableIterator.decorate(set.iterator());
    

    Guava(Google Collections)还有一个不可修改的迭代器,它支持泛型:^{}用法:

    Iterators.unmodifiableIterator(set.iterator());