Java中Iterable和Iterator接口

作者: IT_Matters | 来源:发表于2016-06-13 21:05 被阅读3390次

    接口定义

    public interface Iterable<T> {
      Iterator<T> iterator();
    }
    
    public interface Iterator<E> {
      boolean hasNext();
      E next();
      void remove();
    }
    

    Iterable只是返回了Iterator接口的一个实例,这里很是奇怪,为什么不把两个接口合二为一,直接在Iterable里面定义hasNext(),next()等方法呢?

    原因是实现了Iterable的类可以在实现多个Iterator内部类,例如LinkedList中的ListItrDescendingIterator两个内部类,就分别实现了双向遍历和逆序遍历。通过返回不同的Iterator实现不同的遍历方式,这样更加灵活。如果把两个接口合并,就没法返回不同的Iterator实现类了。

    上个代码,直观地展示一下实现了Iterable的类如何通过返回不同的Iterator从而实现不同的遍历方式。MutilIterator实现了三种迭代器,分别是默认的前向迭代器,反向迭代器和随机迭代器。主函数中分别调用了三种迭代器进行遍历。

    代码示例

    MutilIterator.java

    import java.util.*;
    
    public class MutilIterator implements Iterable<String> {
     private String[] words = "May I get offers this summer.".split(" ");
    
        //默认的迭代器,前向遍历
        public Iterator<String> iterator() {
           //匿名内部类
            return new Iterator<String>() {
                private int index = 0;
                public boolean hasNext() {return index < words.length;}
                public String next() { return words[index++];    }
                public void remove() { // Not implemented
                    throw new UnsupportedOperationException();
                }
            };
        }
    
    //反向迭代器
        public Iterable<String> reverseIterator() {
            return new Iterable<String>() {
                @Override
                public Iterator<String> iterator() {
                    return new Iterator<String>() {
                        private int index = words.length - 1;
                        public boolean hasNext() {return index > -1; }
                        public String next() {return words[index--]; }
                        public void remove() { // Not implemented
                            throw new UnsupportedOperationException();
                        }
                    };
                }
            };
        }
    //随机迭代器,注意这里不是创建一个新的Iterator,而是返回了一个打乱的List中的迭代器
        public Iterable<String> randomized() {
            return new Iterable<String>() {
                public Iterator<String> iterator() {
                    List<String> shuffled = new ArrayList<>(Arrays.asList(words));
                    Collections.shuffle(shuffled, new Random(47));
                    return shuffled.iterator();
                }
            };
        }
    public static void main(String[] args) {
            MutilIterator mi = new MutilIterator();
           //默认的迭代器
            for (String String : mi) {
                System.out.print(String + " ");
            }
            System.out.println();
           //反向迭代器
            for (String String : mi.reverseIterator()) {
                System.out.print(String + " ");
            }
            System.out.println();
            //随机迭代器
            for (String String : mi.randomized()) {
                System.out.print(String + " ");
            }
        }/*Output:
      May I get offers this summer. 
      summer. this offers get I May 
      I this offers summer. May get 
    *///
    

    结论:

    Java容器中,所有的Collection子类会实现Iteratable接口以实现foreach功能,Iteratable接口的实现又依赖于实现了Iterator的内部类(参照LinkedListlistIterator()descendingIterator()的JDK源码)。有的容器类会有多个实现Iterator接口的内部类,通过返回不同的迭代器实现不同的迭代方式。

    相关文章

      网友评论

      • 5ff2a3776d92:说的不对,
        苦寒行:其实也不是说不对,只是你的文章在解释为什么jdk中的集合类大都实现iterable接口而不是iterator接口。也涉及到一部分iterable和iterator的区别。
        IT_Matters:哪里不对?还请指教
        63a590e140ae: @背骑蠢驴挂剑浪天涯 ??

      本文标题:Java中Iterable和Iterator接口

      本文链接:https://www.haomeiwen.com/subject/izwydttx.html