zoukankan      html  css  js  c++  java
  • java迭代器

    迭代器

    不同java集合(容器)的内部结构是不一样的,如果为每种容器都单独实现一种遍历方法十分麻烦,为了简化遍历容器的操作,所以推出了java迭代器(Iterator)

    通过java迭代器,我们可以用统一的方法实现对容器的遍历,极大地简化了操作.

    迭代器接口

    1.java.util.Iterator接口

      

    public interface Iterator<E> {
        //查询容器中是否存在下一个元素
        boolean hasNext();
        //返回下一个元素
        //注意 : 在一次循环中,只能用一次next(),重复调用会返回再下面的元素.
        E next();
        //把元素从容器中移除
        //注意 : 要用迭代器的remove()方法,不要用容器的remove()方法.否则会发生异常
        default void remove() {
            throw new UnsupportedOperationException("remove");
        }
        //1.8新增默认方法,以后再讲
        default void forEachRemaining(Consumer<? super E> action) {
            Objects.requireNonNull(action);
            while (hasNext())
                action.accept(next());
        }
    }
    

    2.java.util.Iterable

    public interface Iterable<T> {
        //容器可以通过此方法,返回该容器的迭代器.
        Iterator<T> iterator();
        //1.8新增,先不讲
        default void forEach(Consumer<? super T> action) {
            Objects.requireNonNull(action);
            for (T t : this) {
                action.accept(t);
            }
        }
        //1.8新增,先不讲
        default Spliterator<T> spliterator() {
            return Spliterators.spliteratorUnknownSize(iterator(), 0);
        }
    }  

    Collection<E>接口继承了Iterable<T>接口,而Iterable接口含有iterator()方法,所以 : 

      所有继承自Collection<E>的容器,都实现了iterator()方法,从而通过此方法获得各自容器的迭代器!

    如何使用迭代器遍历集合

    List<String> list =new ArrayList<String>();
    //给list添加元素的过程省略......
    Iterator<String> listIterator = list.iterator();
    while(listIterator.hasNext()) {
        //一次循环中只能调用一次next()方法!否则循环就乱套了!
        //因为每次调用next()都会获取下一个元素.
        String next = listIterator.next();
        if("bingo".equals(next)) {
        //只能通过迭代器删除元素,用集合的remove()方法会发生异常!
        listIterator.remove();
        //❌这是错误方法❌
        //list.remove(next);
        }else {
            System.out.println(next);
         }
    }
    System.out.println(list);    

    如果遍历的是Map,那么用Map的entrySet()方法获得Set<Entry<K, V>>,通过Set来获取迭代器!(Map.Entry是一个键值对)

    //Map通过entrySet()方法获取Set,再获取Set的迭代器
    Iterator<Entry<Integer, String>> iterator =map.entrySet().iterator();
    //之后的操作同上.
    

      用Map.Entry的getKey()方法获取键,getValue()方法获取值.

    ListIterator和Iterator的区别

    迭代List集合时,推荐使用ListIterator

      1. iterator()方法在set和list接口中都有定义,但是ListIterator()仅存在于list接口中(或实现类中);

      2. ListIterator有add()方法,可以向List中添加对象,而Iterator不能

      3. ListIterator和Iterator都有hasNext()和next()方法,可以实现顺序向后遍历,但是ListIterator有hasPrevious()和previous()方法,可以实现逆向(顺序向前)遍历。Iterator就不可以。

      4. ListIterator可以定位当前的索引位置,nextIndex()和previousIndex()可以实现。Iterator没有此功能。

      5. 都可实现删除对象,但是ListIterator可以实现对象的修改,set()方法可以实现。Iierator仅能遍历,不能修改。  

      因为ListIterator的这些功能,可以实现对LinkedList等List数据结构的操作。其实,数组对象也可以用迭代器来实现。

    为什么迭代器遍历时不能用集合的remove()方法删除元素?

      会发生异常,具体以后再写.

    for增强循环

    for增强循环实际上内部也是使用的迭代器进行遍历.所以for增强循环在遍历集合时也不能删除元素(用集合的remove()方法)

    for循环和迭代器谁更快?

    主要看遍历的集合的数据结构是否合适 : 

      for循环依据索引来遍历对象,所以在随机访问中比较快(比如ArrayList)

      迭代器的next()采用的是顺序访问方法,所以在顺序访问的集合中速度更快(比如LinkedList)

  • 相关阅读:
    java代码 分解EXCEL(一)
    hdu 1226 BFS + bfs记录路径
    MVC-MODEL
    弱类型、强类型、动态类型、静态类型语言的区别是什么?
    Objective-C中的命名前缀说明
    self & this 上下文
    Object comparison
    Dynamic typing 动态类型
    iOS支付宝 9.x 版本首页效果
    Using an Image for the Layer’s Content
  • 原文地址:https://www.cnblogs.com/jinyu59/p/10658666.html
Copyright © 2011-2022 走看看