我是靠谱客的博主 眼睛大皮卡丘,最近开发中收集的这篇文章主要介绍java中for、foreach(增强for)和stream中foreach的性能和原理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

for循环是java出生的时候就已经支持了,在jdk 1.5中开始支持 foreach 循环,foreach 在一定程度上简化了集合的遍历,但是由于场景的局限性不能完全替代 for 循环,stream是jdk 1.8中开始支持的,功能强大,效率也还行。
public static void main(String[] args) {
        List<Integer> array = new ArrayList<Integer>();
        List<Integer> link = new LinkedList<Integer>();

        long startTime = 0;
        long endTime = 0;
        int num = 150000;

        startTime=System.currentTimeMillis();
        for(int i=0; i<num; i++) {
            array.add(i);
        }
        endTime=System.currentTimeMillis();
        System.out.println("ArrayList add 花费时间: " + (endTime - startTime));

        startTime=System.currentTimeMillis();
        for(int i=0; i<num; i++) {
            link.add(i);
        }
        endTime=System.currentTimeMillis();
        System.out.println("LinkedList add 花费时间: " + (endTime - startTime));

        startTime=System.currentTimeMillis();
        for(int i=0; i<num; i++) {
            array.get(i);
        }
        endTime=System.currentTimeMillis();
        System.out.println("for 遍历  ArrayList get 花费时间: " + (endTime - startTime));

        startTime=System.currentTimeMillis();
        for(int i=0; i<num; i++) {
            link.get(i);
        }
        endTime=System.currentTimeMillis();
        System.out.println("for 遍历 LinkedList get 花费时间: " + (endTime - startTime));

        startTime=System.currentTimeMillis();
        for(int i : array) {
//            System.out.print(i+"r");
        }
        endTime=System.currentTimeMillis();
        System.out.println("forEach 遍历  ArrayList get 花费时间: " + (endTime - startTime));

        startTime=System.currentTimeMillis();
        for(int i : link) {
//            System.out.print(i+"r");
        }
        endTime=System.currentTimeMillis();
        System.out.println("forEach 遍历 LinkedList get 花费时间: " + (endTime - startTime));

        startTime=System.currentTimeMillis();
        array.stream().forEach(item -> {});
        endTime=System.currentTimeMillis();
        System.out.println("stream 遍历 LinkedList get 花费时间: " + (endTime - startTime));

        startTime=System.currentTimeMillis();
        link.stream().forEach(item -> {});
        endTime=System.currentTimeMillis();
        System.out.println("stream 遍历 LinkedList get 花费时间: " + (endTime - startTime));
    }

运行结果

ArrayList:ArrayList是采用数组的形式保存对象的,这种方式将对象放在连续的内存块中,所以插入和删除时比较麻烦,当然在新增的时候遇到需要扩容也是麻烦的,查询比较方便。
LinkList:LinkList是将对象放在独立的空间中,而且每个空间中还保存前后一个空间的索引,也就是数据结构中的链表结构,插入和删除比较方便,但是查找很麻烦,要从第一个开始遍历。


运行结果表明

  • 用for循环arrayList 15万次花费时间:3毫秒;用for循环linkList 15万次花费时间:9579毫秒。
  • 用foreach循环arrayList 15万次花费时间:5毫秒;用foreach循环linkList 15万次花费时间:2毫秒。
  • 用stream中foreach循环arrayList 15万次花费时间:37毫秒。 用foreach循环linkList 15万次花费时间:3毫秒。

循环ArrayList时,普通for循环比foreach循环花费的时间要少一点,stream耗时明显偏大。
循环LinkList时,stream和foreach循环花费的时间差不多,普通for耗时明显大了好多倍。

for循环是通过下标来遍历获取对应的元素,ArrayList是数组结果所以下标获取很快,LinkedList是链表结构,每次通过下标去获取是都是从第一个节点开始往后查找,所以耗时多。
foreach循环是通过迭代器来遍历的,遍历ArrayList时需要先将数组转为对应的引用类型,因为数组没有实现Iterable接口,遍历LinkedList时直接通过顺序IO来遍历的,所以遍历耗时差不多。
stream循环是通过可分迭代器Spliterator来遍历,分为并行流和普通的顺序流,为了实现强大的功能必然对性能有所影响,所以并不是最快的。

结论

  1. 需要循环数组结构的数据时,建议使用普通for循环,因为for循环采用下标访问,对于数组结构的数据来说,采用下标访问稍微好点,而且还可以满足对list本身的修改。
  2. 需要循环链表结构的数据时,一定不要使用普通for循环,这种做法很糟糕,数据量大的时候有可能会导致系统崩溃,foreach循环性能虽好但是无法修改list本身,可以优先考虑使用stream。

最后

以上就是眼睛大皮卡丘为你收集整理的java中for、foreach(增强for)和stream中foreach的性能和原理的全部内容,希望文章能够帮你解决java中for、foreach(增强for)和stream中foreach的性能和原理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部