美文网首页
Iterable、Iterator、foreach

Iterable、Iterator、foreach

作者: 最后的轻语_dd43 | 来源:发表于2019-06-13 15:24 被阅读0次

1. Iterable简介

实现此接口的对象支持迭代,允许该对象成为增强型for语句(有时称为“for-each”语句)的目标。

Iterable接口中只有一个iterator()方法(JDK8及8以后新增两个default方法),该方法返回Iterator类型对象。

public interface Iterable<T> {
  
    Iterator<T> iterator();
   ...
}

2. Iterator简介

实现此接口的对象就会成为迭代器,提供迭代机制。

通过hasNext查找是否还有下一个元素,并在hasNext返回true时反复地调用next方法,获取下一个元素。

public interface Iterator<E> {

    boolean hasNext();
    E next();
    void remove();
    ...
}

3. Iterable和Iterator关系

Iterable是一个对象拥有被迭代的“资格”,而Iterator是一个真正干事的迭代器。

3.1 发现问题

我们通过一个测试程序来对这两个接口进行说明。源码如下:

这是一个能够动态调整数组大小的栈。

/**
 * Resizing array stack
 * @author lastwhisper
 */
public class ResizingArrayStack<Item>{
    private Item[] a;// stack entries
    private int N;// size

    // Create a empty stack of size cap.
    public ResizingArrayStack(int cap) {
        a = (Item[]) new Object[cap];
    }

    // Add a item.
    public void push(Item item) {
        if (N == a.length) {
            resize(2 * a.length);
        }
        a[N++] = item;
    }

    // Delete recently added item.
    public Item pop() {
        Item item = a[--N];
        a[N] = null;
        if (N > 0 && N == a.length / 4) {
            resize(a.length / 2);
        }
        return item;
    }

    // Is the stack empty?
    public boolean isEmpty() {
        return N == 0;
    }

    // The numebr of items int the stack
    public int size() {
        return N;
    }

    private void resize(int max) {
        // Move the stack of size N<=max to a new array of size max.
        Item[] temp = (Item[]) new Object[max];
        for (int i = 0; i < temp.length; i++) {
            temp[i] = a[i];
        }
        a = temp;
    }
}

我们如何来遍历这个栈呢?通常我们会使用foreach遍历。

/**
 * @author lastwhisper
 */
public class IterableAndIterator {
    public static void main(String[] args) {
        ResizingArrayStack<String> stack = new ResizingArrayStack<String>(100);
        stack.push("1");
        stack.push("2");
        stack.push("3");
        for (String s : stack) {
            System.out.printf("%s ",s);
        }
    }
}

但是编译器却报错说,foreach不能应用ResizingArrayStack类上。

foreach

这是因为foreach只是一个语法糖,本质上使用的还是使用迭代器遍历的,ResizingArrayStack并没有实现Iterable接口,所以无法被迭代!

3.2 解决问题

将ResizingArrayStack实现Iterable接口,并提供对应实现的迭代器。

/**
 * Resizing array stack
 * @author lastwhisper
 */
public class ResizingArrayStack<Item> implements Iterable<Item> {
    
    ...

    @Override
    public Iterator<Item> iterator() {
        return new ReverseArrayIterator();
    }

    private class ReverseArrayIterator implements Iterator<Item> {

        private int i = N;

        @Override
        public boolean hasNext() {
            return i > 0;
        }

        @Override
        public Item next() {
            return a[--i];
        }

        @Override
        public void remove() {

        }
    }

}

此时就可以使用foreach遍历,也可以使用迭代遍历。

/**
 * @author lastwhisper
 */
public class IterableAndIterator {
    public static void main(String[] args) {
        ResizingArrayStack<String> stack = new ResizingArrayStack<String>(100);
        stack.push("1");
        stack.push("2");
        stack.push("3");
        // foreach
        for (String s : stack) {
            System.out.printf("%s ",s);
        }
        // iterator
        Iterator<String> iterator = stack.iterator();
        while (iterator.hasNext()){
            String temp = iterator.next();
            System.out.printf("%s ",temp);
        }
    }
}

4. foreach遍历与iterator遍历

foreach只是一种语法糖,foreach遍历本质上就是使用iterator遍历。
在java文件编译为class文件之后语法糖就会被消除,露出它的本质。

将带有foreach遍历的class文件,进行反编译(我使用的是jad反编译工具)。

for (String s : stack) {
      System.out.printf("%s ", s);
}

将class文件反编译后foreach遍历被翻译为iterator遍历

String s;
for (Iterator iterator = stack.iterator(); iterator.hasNext();
      System.out.printf("%s ", new Object[]{s}))
s = (String) iterator.next();

或者这样(http://javare.cn

Iterator var2 = stack.iterator();
while(var2.hasNext()) {
        String s = (String)var2.next();
        System.out.printf("%s ", new Object[]{s});
}

相关文章

网友评论

      本文标题:Iterable、Iterator、foreach

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