[关闭]
@w1024020103 2017-01-11T00:24:56.000000Z 字数 2710 阅读 512

What is the difference between iterator and iterable and how to use them?

java iterator iterable stackoverflow jianshu


StackOverflow

Question:

I am new in Java and I'm really confused with iterator and iterable. Can anyone explane to me and give some examples?

Answer:

An Iterable is a simple representation of a series of elements that can be iterated over. It does not have any iteration state such as a "current element". Instead, it has one method that produces an Iterator.

An Iterator is the object with iteration state. It lets you check if it has more elements using hasNext() and move to the next element (if any) using next().

Typically, an Iterable should be able to produce any number of valid Iterators.

Jianshu

接口定义

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

  1. import java.util.*;
  2. public class MutilIterator implements Iterable<String> {
  3. private String[] words = "May I get offers this summer.".split(" ");
  4. //默认的迭代器,前向遍历
  5. public Iterator<String> iterator() {
  6. //匿名内部类
  7. return new Iterator<String>() {
  8. private int index = 0;
  9. public boolean hasNext() {return index < words.length;}
  10. public String next() { return words[index++]; }
  11. public void remove() { // Not implemented
  12. throw new UnsupportedOperationException();
  13. }
  14. };
  15. }
  16. //反向迭代器
  17. public Iterable<String> reverseIterator() {
  18. return new Iterable<String>() {
  19. @Override
  20. public Iterator<String> iterator() {
  21. return new Iterator<String>() {
  22. private int index = words.length - 1;
  23. public boolean hasNext() {return index > -1; }
  24. public String next() {return words[index--]; }
  25. public void remove() { // Not implemented
  26. throw new UnsupportedOperationException();
  27. }
  28. };
  29. }
  30. };
  31. }
  32. //随机迭代器,注意这里不是创建一个新的Iterator,而是返回了一个打乱的List中的迭代器
  33. public Iterable<String> randomized() {
  34. return new Iterable<String>() {
  35. public Iterator<String> iterator() {
  36. List<String> shuffled = new ArrayList<>(Arrays.asList(words));
  37. Collections.shuffle(shuffled, new Random(47));
  38. return shuffled.iterator();
  39. }
  40. };
  41. }
  42. public static void main(String[] args) {
  43. MutilIterator mi = new MutilIterator();
  44. //默认的迭代器
  45. for (String String : mi) {
  46. System.out.print(String + " ");
  47. }
  48. System.out.println();
  49. //反向迭代器
  50. for (String String : mi.reverseIterator()) {
  51. System.out.print(String + " ");
  52. }
  53. System.out.println();
  54. //随机迭代器
  55. for (String String : mi.randomized()) {
  56. System.out.print(String + " ");
  57. }
  58. }/*Output:
  59.   May I get offers this summer.
  60.   summer. this offers get I May
  61.   I this offers summer. May get
  62. *///

结论:

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

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注