美文网首页
java增强型for循环

java增强型for循环

作者: small瓜瓜 | 来源:发表于2019-07-07 08:56 被阅读0次

增强型for循环是jdk1.5的新特性,使用更加方便,书写简洁。

比如:

        int[] as = {
                1,2,3,5
        };
        for (int a : as) {
            System.out.println("a = " + a);
        }

在比如:

        List<Integer> integerList = new ArrayList<>();
        for (Integer integer : integerList) {
            System.out.println("integer = " + integer);
        }

用这种方式代码更加简洁,可读性强。
这么方便的东西我们怎么能放过呢?接下来就一起实现一个自己的增强型for循环吧
首先看看List的继承图:



最上层是一个Iterable接口。看看它的源码注释的描述:

Implementing this interface allows an object to be the target of the "for-each loop" statement. See For-each Loop

显然这就是可以使用for循环的原因了,先贴出Iterable源码,接下来我们编写一个类来实现这个接口。

public interface Iterable<T> {
    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    Iterator<T> iterator();

    /**
     * Performs the given action for each element of the {@code Iterable}
     * until all elements have been processed or the action throws an
     * exception.  Unless otherwise specified by the implementing class,
     * actions are performed in the order of iteration (if an iteration order
     * is specified).  Exceptions thrown by the action are relayed to the
     * caller.
     *
     * @implSpec
     * <p>The default implementation behaves as if:
     * <pre>{@code
     *     for (T t : this)
     *         action.accept(t);
     * }</pre>
     *
     * @param action The action to be performed for each element
     * @throws NullPointerException if the specified action is null
     * @since 1.8
     */
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    /**
     * Creates a {@link Spliterator} over the elements described by this
     * {@code Iterable}.
     *
     * @implSpec
     * The default implementation creates an
     * <em><a href="Spliterator.html#binding">early-binding</a></em>
     * spliterator from the iterable's {@code Iterator}.  The spliterator
     * inherits the <em>fail-fast</em> properties of the iterable's iterator.
     *
     * @implNote
     * The default implementation should usually be overridden.  The
     * spliterator returned by the default implementation has poor splitting
     * capabilities, is unsized, and does not report any spliterator
     * characteristics. Implementing classes can nearly always provide a
     * better implementation.
     *
     * @return a {@code Spliterator} over the elements described by this
     * {@code Iterable}.
     * @since 1.8
     */
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

看源码知道实现这个接口,要实现方法iterator,返回值是Iterator<T>,这又是一个接口,我们可以在定义的类的内部编写内部类实现Iterator<T>。
下面贴出实现代码:

import java.util.Iterator;

public class MyList implements Iterable<Integer> {

    private Integer[] integers;

    public MyList(Integer[] integers) {
        this.integers = integers;
    }

    @Override
    public Iterator<Integer> iterator() {
        return new MyIterable();
    }

    class MyIterable implements Iterator<Integer> {
        private int index;

        @Override
        public boolean hasNext() {
            return index < integers.length;
        }

        @Override
        public Integer next() {
            return integers[index++];
        }
    }
}

编写以下代码进行测试:

        MyList integers = new MyList(new Integer[]{1, 2, 3});
        for (Integer integer : integers) {
            System.out.println("integer = " + integer);
        }

到此就实现了自己的可使用增强型for循环的类,为了能更深入的理解,不妨给自己提一个问题。为什么可以这样,我们最开始学习java语法规则就只学过三种循环for(;;),while(),do{}while(),这个新出来的循环是怎么实现的呢?jvm层面还是编译器层面?
接下来我们来看看上面写的代码反编译后的样子(idea反编译):

        MyList integers = new MyList(new Integer[]{1, 2, 3});
        Iterator var2 = integers.iterator();

        while(var2.hasNext()) {
            Integer integer = (Integer)var2.next();
            System.out.println("integer = " + integer);
        }
idea反编译代码

其实我们编写的代码是编译器帮我们转换成了传统的循环了,这就是为什么要实现Iterable和Iterator接口了。
但是问题又来了,数组为什么可以用增强型for循环呢?它并没有实现这些接口啊,而且也不可能有next,hasNext方法。它是怎么实现的呢?
编写以下例子:

    public static void main(String[] args) {
        int[] as = {
                1,2,3,5
        };
        for (int a : as) {
            System.out.println("a = " + a);
        }
    }

下面是它反编译后的代码:

    public static void main(String[] args) {
        int[] as = new int[]{1, 2, 3, 5};
        int[] var2 = as;
        int var3 = as.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            int a = var2[var4];
            System.out.println("a = " + a);
        }
    }

看到这里所有迷团都解开了,简单说,对于JVM来说,增强型for循环其实就是传统循环。只是对于程序员来说有了变化。
这属于"挂羊头买狗肉"吗,哈哈,不过这样的确方便了不少,如果让我们写上反编译后的代码,那是有多麻烦啊。

相关文章

  • 从源码解读Java列表的遍历效率

    Java列表应该如何遍历效率更好? Java有三种遍历的方式: 普通for循环遍历(for) 增强型for循环遍历...

  • 为什么遍历LinkedList要用增强型for循环

    for循环和链表介绍 我们都知道java中有个增强型for循环,这个for循环很方便,如果不需要知道当前遍历到第几...

  • java增强型for循环

    增强型for循环是jdk1.5的新特性,使用更加方便,书写简洁。 比如: 在比如: 用这种方式代码更加简洁,可读性...

  • Java 增强型的for循环 for each

    For-Each循环 For-Each循环也叫增强型的for循环,或者叫foreach循环。 For-Each循环...

  • for循环增强型

    package Structure; public class ForPractice4 {public stat...

  • List集合三种遍历方法

    1.迭代器Iterator;2.增强型for循环(foreach);3.普通for循环; 创建ArryList,往...

  • 增强型循环Foreach

    普通循环int[] arr= {a,b,c,d};for(int i=0;i

  • Java的for循环

    Java有好几种循环语句。 for循环是Java的循环之一。for循环在java中用于重复执行一些语句,直到条件返...

  • 迭代器与foreach

    对于“foreach”增强型for循环和集合框架中的“Iterator”想必都不会陌生,今天记录一下关于“迭代器”...

  • java中的循环语句有哪些

    java中的循环语句有哪些 Java中有三种主要的循环结构: while 循环 do…while 循环 for 循...

网友评论

      本文标题:java增强型for循环

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