【小家java】java8新特性之---外部迭代和内部迭代(对比性能差异)

相关阅读

【小家java】java5新特性(简述十大新特性) 重要一跃
【小家java】java6新特性(简述十大新特性) 鸡肋升级
【小家java】java7新特性(简述八大新特性) 不温不火
【小家java】java8新特性(简述十大新特性) 饱受赞誉
【小家java】java9新特性(简述十大新特性) 褒贬不一
【小家java】java10新特性(简述十大新特性) 小步迭代
【小家java】java11新特性(简述八大新特性) 首个重磅LTS版本


【小家java】java8新特性之—Base64加密和解密原理
【小家java】java8新特性之—反射获取方法参数名
【小家java】java8新特性之—全新的日期、时间API(完全实现了JSR 310规范)
【小家java】java8新特性之—Optional的使用,避免空指针,代替三目运算符
【小家java】java8新特性之—lambda表达式的的原理
【小家java】java8新特性之—函数式接口(Supplier、Consumer、Predicate、Function、UnaryOperator,通往高阶设计的好工具)
【小家java】java8新特性之—方法引用
【小家java】java8新特性之—Stream API 详解 (Map-reduce、Collectors收集器、并行流)
【小家java】java8新特性之—外部迭代和内部迭代(对比性能差异)


每篇一句

到了一定的年龄,不要再去追求一些虚伪虚假的东西了,人的这一生,还得要做自己最想做的事情,听最想听的声音,见最想见的人。

从一个案例开始:遍历一个集合

外部迭代

最传统的方法是用Iterator,当然还以用for i、增强for循环等等。这一类方法叫做外部迭代,意为显式地进行迭代操作,即集合中的元素访问是由一个处于集合外部的东西来控制的,在这里控制着循环的东西就是迭代器。

我们自己定义一个List,叫ContactList:电话本List

public class ContactList extends ArrayList<Integer>{}

里面存他们的编号,现在我们要都输出,可以这么做

for (Iterator<String> contactListIterator = contactList.iterator(); contactListIterator.hasNext(); ) {
    System.out.println(contactListIterator.next());
}
内部迭代

顾名思义,这种方式的遍历将在集合内部进行,我们不会显式地去控制这个循环。无需关心遍历元素的顺序,我们只需要定义对其中每一个元素进行什么样的操作。注意在这种设定下可能无法直接获取到当前元素的下标。
比如JDK8提供的最新的Collection.forEach(…)方法。

forEach方法源码,一看究竟

@Override
public void forEach(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    final int expectedModCount = modCount;
    @SuppressWarnings("unchecked")
    final E[] elementData = (E[]) this.elementData;
    final int size = this.size;
    for (int i=0; modCount == expectedModCount && i < size; i++) {
        action.accept(elementData[i]);
    }
    if (modCount != expectedModCount) {
        throw new ConcurrentModificationException();
    }
}

可以发现其内部依旧是使用了一个for循环遍历本身,只不过对并发做了一些处理而已。可见外部迭代与内部迭代并没有本质上的区别,两者存在形式上的不同。

性能比较

public static void main(String[] args) {
        final long count = 100_00000;
        List<Long> list = new ArrayList<>();
        for (long i = 0; i < count; i++) {
            list.add(i);
        }


        //=========传统方式进行外部迭代=========
        Instant begin = Instant.now();
        for (Long i : list) {
            System.out.print("");
        }
        System.out.println("--------------------------");
        Instant end = Instant.now();
        System.out.println("传统方式进行外部迭代" + count + "次,耗时(ms):" + Duration.between(begin, end).toMillis());


        //=========java8内部迭代,用lambda处理=========
        begin = Instant.now();
        list.stream().forEach(i -> System.out.print(""));
        System.out.println("--------------------------");
        end = Instant.now();
        System.out.println("内部迭代forEach" + count + "次,耗时(ms):" + Duration.between(begin, end).toMillis());

        //=========java8进行并行流处理后迭代(备注:并行流输出是没有顺序的 比如不再是1234顺序了)=========
        begin = Instant.now();
        list.parallelStream().forEach(i -> System.out.print(""));
        System.out.println("--------------------------");
        end = Instant.now();
        System.out.println("内部迭代parallelStream" + count + "次,耗时(ms):" + Duration.between(begin, end).toMillis());
    }

这段代码,有兴趣的各位可以去执行,对比一下效率。

结论

java的内部迭代的推出,使得我们具备了一定的流式处理的能力。特别是当数据量大的时候,一定要使用Stream迭代,内部迭代。

知识交流

【小家java】java8新特性之---外部迭代和内部迭代(对比性能差异)_第1张图片
若群二维码失效,请加微信号(或者扫描下方二维码):fsx641385712。
并且备注:“java入群” 字样,会手动邀请入群

【小家java】java8新特性之---外部迭代和内部迭代(对比性能差异)_第2张图片

你可能感兴趣的:(享学Java)