zoukankan      html  css  js  c++  java
  • Java中的集合迭代器

    集合的迭代器

    任何集合都有迭代器。

    任何集合类,都必须能以某种方式存取元素,否则这个集合容器就没有任何意义。

    迭代器,也是一种模式(也叫迭代器模式)。在java中它是一个对象,其目的是遍历并选中其中的每个元素,而使用者(客户端)无需知道里面的具体细节。迭代器要足够的“轻量”——创建迭代器的代价小。所以看迭代器的源代码就会发现,里面会有很多要求:

    1. iterator方法返回一个Iterator,Iterator返回序列的头元素。
    2. next方法获取下一个元素
    3. hasNext检查还有元素
    4. remove删除迭代器新返回的元素

    下面是迭代器的基本使用

    public class UsingIterator {
        public static void main(String[] args) {
            List<String> names = Arrays.asList("marson", "shine", "summer", "zhu");
            Iterator<String> it = names.iterator();
            while(it.hasNext()){
                String s = it.next();
                print(s);
            }
            for (String s : names){
                print(s);
            }
            System.out.println();
            it = names.iterator();
            for (int i = 0; i < 4; i++) {
                it.next();
            }
            print(names);
        }
    }
    

    ListIterator

    ListIterator是一个更强大的Iterator子类型,能用于各种List类访问,前面说过Iterator支持单向取数据,ListIterator可以双向移动,所以能指出迭代器当前位置的前一个和后一个索引,可以用set方法替换它访问过的最后一个元素。我们可以通过调用listIterator方法产生一个指向List开始处的ListIterator,并且还可以用过重载方法listIterator(n)来创建一个指定列表索引为n的元素的ListIterator。

    public class ListIteration {
        public static void main(String[] args) {
            var names = Arrays.asList("marson", "shine", "summer", "zhu");
            var it = names.listIterator();
            while (it.hasNext()) {
                print(it.next() + ", " + it.nextIndex() + ", " + it.previousIndex() + "; ");
            }
    
            while (it.hasPrevious()) {
                print(it.previous() + " ");
            }
            print(names);
    
            it = names.listIterator(3);
            while (it.hasNext()) {
                it.next();
                it.set("alias");
            }
            print(names);
        }
    }
    

    输出结果为:


    marson, 1, 0;
    shine, 2, 1;
    summer, 3, 2;
    zhu, 4, 3;
    zhu
    summer
    shine
    marson
    [marson, shine, summer, zhu]
    [marson, shine, summer, alias]

    Iterator模式

    前面说了,迭代器又叫迭代器模式,顾名思义,只要符合这种模式都能叫迭代器模式,自然也能像前面一样使用迭代器

    那么Iterator模式具体是个什么样子的模式呢?

    我们通过Collection的源码发现其中的样子(为什么要看Collection而不是其他的List?因为Collection是所有容器的基类啊)

    通过Collection代码我们发现它继承了一个叫Iterable<T>接口,注解说的很清楚——实现这个接口就说明这个对象是可迭代的;并且其成员函数也很清晰,只有三个方法

    public interface Iterable<T> {
    	Iterator<T> iterator();
    	default void forEach(Consumer<? super T> action);	//省略部分代码
    	default Spliterator<T> spliterator();	//省略部分代码
    }
    public interface Iterator<E> {
      	boolean hasNext();
      	E next();
      	default void remove() {
            throw new UnsupportedOperationException("remove");
        }
      	...
    }
    

    Iterator这个泛型接口才是我们真正实现迭代的核心,通过这些信息我们尝试来写一个迭代器

    public class CustomIterator implements Iterable<String> {
        protected String[] names = ("marson shine summer zhu").split(" ");
        public Iterator<String> iterator() {
            return new Iterator<String>() {
                private int index = 0;
                @Override
                public boolean hasNext() {
                    return index < names.length;
                }
                @Override
                public String next() {
                    return names[index++];
                }
                public void remove() {
                }
            };
        }
        public static void main(String[] agrs) {
            for (var s : new CustomIterator()) {
                print(s + " ");
            }
        }
    }
    

    到这里,自定义的迭代器就写完了,实际上我们只需要继承一个Iterable接口然后实现这个接口就行了,更深入的话,其实还可以自己写一个listIterator实现双向的操作数据

  • 相关阅读:
    spring整合myBatis
    spring之事物
    spring之AspectJ实现AOP
    AOP之JDK动态代理和CGLib动态代理
    iOS-面试相关<一>
    iOS -调试工具Instruments使用总结
    iOS-阅读器常年崩溃问题记录
    iOS
    ios
    iOS
  • 原文地址:https://www.cnblogs.com/ms27946/p/Iterable-Iterator-In-Java.html
Copyright © 2011-2022 走看看