java源码之Iterator
- 前言
- 方法
- hasNext
- next
- remove
- forEachRemaining
前言
Iterator是collection 的一个迭代器,它取代了Java集合 框架下的枚举接口,与枚举接口不同的是:
1、调用者可以使用迭代器并通过已经定义明确的语法对迭代中的集合进行删除操作;
2、其方法名有了一定的优化。
在jdk1.0引入Enumration对集合进行迭代,其有两个方法即:hasMoreElements和nextElement,分别用老判断是否有含有更多的元素和获取下一个元素,与Iterator的hasNext与next类似。
在jdk1.2添加了Iterator作为集合的默认迭代器。
方法
hasNext
- jdk源码
boolean hasNext();
判断迭代器中是否还有元素
- demo
public static void main(String[] args) {
List<String> strings= new ArrayList<>();
System.out.println(strings.iterator().hasNext());
}
当strings中含有元素时,控制台会输出true;
当strings中不含有元素时,控制台会输出false;
next
- jdk源码
E next();
获取迭代器中的下一个元素
- demo
public static void main(String[] args) {
List<String> strings= new ArrayList<>();
strings.add("a");
Iterator<String> iterable = strings.iterator();
System.out.println(iterable.next());
System.out.println(iterable.next());
}
从代码中可以看出来strings中只有一个元素,第一次进行next操作返回的是其中的元素a,第二次进行next操作迭代器中没有元素,这是产生了一个异常NoSuchElementException。
remove
- jdk源码
default void remove() {
throw new UnsupportedOperationException("remove");
}
- demo
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
Iterator<String> iterator = strings.iterator();
Object item = iterator.next();
iterator.remove();
}
代码调用remove之前数组为[a,b];调用之后为[b],相关元素已移除。
tips: 如果代码没有调用next直接调用remove会抛出IllegalStateException,因为remove是删除当前指针指向的元素,当没有掉用next时,当前指针没有元素。Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则,Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。
所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。
forEachRemaining
- jdk源码
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
循环调用迭代器执行某个操作
- demo
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
Iterator<String> iterator = strings.iterator();
iterator.forEachRemaining(System.out::println);
}
迭代器会将数组中的每一个数据打印到控制台上