我有一个使用HashSet
的类,我想要类实现Iterable
,但我不希望类迭代器支持remove()
方法。
HashSet
的默认迭代器是HashSet.KeyIterator
,它是HashSet
类中的私有类,所以我不能简单地扩展它并覆盖remove方法。
理想情况下,我想避免为KeyIterator
编写包装类,但我不知道如何轻松地以其他任何方式简单地实现我自己的迭代器。
有什么想法吗?
干杯,
皮特
答案 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
,但这可能有点过分。