Iterator

文章目录

  • Iterator 接口
    • boolean hasnext()
    • E next()
    • default void remove()
    • default void forEachRemaining(Consumer action)

Iterator 接口

迭代器作用在集合上,是 java 集合框架中 Enumeration 的代替品,因此迭代器同样也是java集合框架下面的成员。迭代器有两个地方不同于 Enumeration。分别如下:

  1. 迭代器允许调用者,在迭代集合元素期间,移除集合的元素。

  2. 名字得到改进,迭代比枚举更容易见名知其义。


boolean hasnext()

如果迭代器还有更多的元素,则返回 true ,否则返回 false 。也就是如果 next() 方法返回的是一个元素而不是抛出异常,则 hasnext() 方法返回 true


E next()

返回迭代器中的下一个元素。(注意,迭代开始的时候,游标指向表头,所以下一个元素,也就是表的第一个元素)。

可能抛出 NoSuchElementException

  1. 如果迭代器没有更多的元素了,调用 next() 方法,则抛出此异常。

    		Map<String, String> stringMap = new HashMap<>(16);
    
            stringMap.put("key1", "value1");
            stringMap.put("key2", "value2");
            stringMap.put("key3", "value3");
            stringMap.put("key4", "value4");
            stringMap.put("key5", "value5");
            stringMap.put("key6", "value6");
    
            Iterator<Map.Entry<String, String>> iterator = stringMap.entrySet().iterator();
            while (iterator.hasNext()) {
                iterator.next();
            }
            // 抛出异常,此时迭代器已经迭代完毕,没有更多的元素用于迭代了。
            iterator.next();
    
    
  2. 同样的对于一个空的集合的迭代器,使用 next() 方法,也会抛出此异常。

    		Map<String, String> stringMap = new HashMap<>(16);
    
            Iterator<Map.Entry<String, String>> iterator = stringMap.entrySet().iterator();
            // 抛出异常,此时迭代器虽然没有迭代,但是集合本身就是空的,因此也没有更多的元素用于迭代了。
            iterator.next();
    

default void remove()

移除集合中最后一次调用 next() 方法返回的元素。如果你连续三次调用 next() 方法,则第三次调用 next() 方法返回的元素将被异常。

该方法在一次 next() 方法以后,只能被调用一次,也就是两次 next() 方法期间,只能被调用一次,其实也好理解,调用一次 ,当前 next 方法的返回值已经被移除了,再次调用它,还移除谁呢。

如果在迭代器迭代集合的过程中,对集合进行了修改了(非调用此 remove() 方法),迭代器的行为将变得未知。所有,如果想移除元素,请使用该方法。

可能抛出的异常:

  1. UnsupportedOperationException :如果当前迭代器不支持 remove 操作,则抛出此异常。

  2. IllegalStateException :如果在两次 next()方法期间多次调用 remove() 方法或者,还没有调用 next() 方法,就调用了 remove() 方法,则抛出此异常。

       		Map<String, String> stringMap = new HashMap<>(16);
    
            stringMap.put("key1", "value1");
            stringMap.put("key2", "value2");
            stringMap.put("key3", "value3");
            stringMap.put("key4", "value4");
            stringMap.put("key5", "value5");
            stringMap.put("key6", "value6");
    
            Iterator<Map.Entry<String, String>> iterator = stringMap.entrySet().iterator();
            //  抛出 IllegalStateException
            iterator.remove();
            while (iterator.hasNext()) {
                iterator.next();
                iterator.remove();
                // 抛出 IllegalStateException
                iterator.remove();
            }
    

default void forEachRemaining(Consumer action)

首先需要了解下 函数式接口 Consumer ,以及 lambda 表达式 。再接着看下面的内容。

源码:

default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }

该方法,为迭代器中所有剩余的元素,都执行 Consumer 定义的动作。直到迭代器遍历结束或者抛出异常。如果发生异常,则异常抛出到调用者处。如果没有被复写,则迭代的顺序,就是源代码中的顺序。

可能抛出的异常:NullPointerException ,如果指定的 Consumernull ,则抛出该异常。

注意的是,在执行该方法,会迭代完迭代器的剩余元素。

 	 	Map<String, String> stringMap = new HashMap<>(16);

        stringMap.put("key1", "value1");
        stringMap.put("key2", "value2");
        stringMap.put("key3", "value3");
        stringMap.put("key4", "value4");
        stringMap.put("key5", "value5");
        stringMap.put("key6", "value6");

        Iterator<Map.Entry<String, String>> iterator = stringMap.entrySet().iterator();
        // forEachRemaining 也是迭代了。
        iterator.forEachRemaining((Map.Entry entry) -> {
            // 简单的打印下 key
            System.out.println(entry.getKey());
        });
        // 代码执行到此处,iterator 已经迭代完毕。

你可能感兴趣的:(java基础)