如果我有一个Map或List并从中获取一个迭代器,例如:
var map = new HashMap();
var iterator = map.entrySet().iterator();
如果事后修改了该映射,它将影响迭代器,还是一旦创建该迭代器基本上是不可变的?
如果它不是不可变的,如何创建不可变的迭代器?
答案 0 :(得分:2)
迭代器的唯一有效操作是增量和取消引用(尽管Java Iterator
在其next()
方法中将两者结合在一起)。如果您有一个不可修改的迭代器,则仅需取消引用。取消引用可以为您提供对象引用,也可以无效,因为它没有引用集合中的有效位置。
但是这些语义与Optional
相同:Optional
可以为空或具有有效的对象引用。因此,请从Iterator
创建一个Optional
并将其用作您的“不可修改的迭代器”:
private Optional<T> unmodifiableNext(Iterator<T> i)
{
if (i.hasNext()) {
return Optional.ofNullable(i.next());
} else {
return Optional.empty();
}
}
这还有一个好处,就是Optional
不再与集合绑定,因此可以安全地更改集合,而无需更改Optional
所指向的对象。
答案 1 :(得分:0)
迭代器实例本身通常不需要可变性/不可变性的概念。但是,要迭代的集合可能是不可修改的或不可变的。这是一种禁用迭代器更改集合功能的方法。如果返回此类的实例,则禁用返回的迭代器的remove()方法。通过返回UnmodifiableIterator.create(yourIterator)使用该类。
import java.util.Iterator;
/**
* UnmodifiableIterator, A wrapper around an iterator instance that
* disables the remove method.
*/
public final class UnmodifiableIterator<E> implements Iterator<E> {
/**
* iterator, The base iterator.
*/
private final Iterator<? extends E> iterator;
private UnmodifiableIterator(final Iterator<? extends E> iterator) {
this.iterator = iterator;
}
public static <E> Iterator<E> create(final Iterator<? extends E> iterator) {
if (iterator == null) {
throw new NullPointerException("The iterator can not be null.");
}
return new UnmodifiableIterator<>(iterator);
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public E next() {
return iterator.next();
}
@Override
public void remove() {
throw new UnsupportedOperationException("Iterator.remove() is disabled.");
}
}