您的位置:首页 > 编程语言 > Java开发

Java 8之Stream适用场景

2015-08-14 17:53 477 查看
Stream是Java 8中的一个大的改进。Stream的功能是,支持集合的各种操作,比如filter, sum, max, min, average, map, reduce等等。所以我个人认为Stream的出现是基于以下原因:

增强集合操作

拥抱函数式编程

充分利用Lambda

执行效率的提高 - 透明支持多线程集合操作

笔者尝试测试一下Stream并发处理的威力,发现面对特别简单的任务,Stream并发处理相较于传统的for each循环,执行效率没有优势。看起来Stream不是免费的午餐,创建Stream还是要一些开销的。所以这促使笔者思考该在什么场景下才使用Stream。

测试例子

笔者测试两个例子,一个任务非常简单,另外一个稍微复杂一点。从结果看起来,并行Stream总是比串行快,任务简单的情况,For Loop更快,任务复杂一点,并行Stream后来居上,并行带来的改进足以cover创建Stream的开销。

测试的小工具类

public class TimeRecorder {
    private long startTime;
    private long endTime;

    public void start() {
        startTime = System.currentTimeMillis();
    }

    public long end() {
        endTime = System.currentTimeMillis();
        return endTime - startTime;
    }

    public long getDuration() {
        return endTime - startTime;
    }

}


任务非常简单的例子

只调用intValue这么一个小方法。

public class StreamDemoSimple {
    public static void main(String[] args) {
        List<Integer> intList = new LinkedList<Integer>();
        for (int i = 1; i <= 1000000; i++) {
            intList.add(i);
        }

        TimeRecorder recorder = new TimeRecorder();

        recorder.start();
        intList.stream().forEach(i -> {
            i.intValue();
        });
        recorder.end();
        System.out.print("Stream iterator:");
        System.out.println(recorder.getDuration());

        recorder.start();
        intList.parallelStream().forEach(i -> {
            i.intValue();
        });
        recorder.end();
        System.out.print("Parallel Stream iterator:");
        System.out.println(recorder.getDuration());

        recorder.start();
        for (Integer i : intList) {
            i.intValue();
        }
        recorder.end();
        System.out.print("Normal iterator:");
        System.out.println(recorder.getDuration());
    }
}


输出如下:

Stream iterator:447

Parallel Stream iterator:142

Normal iterator:70

任务稍微复杂的例子

多执行了几步而已。

public class StreamDemo {
    public static void main(String[] args) {
        List<Integer> intList = new LinkedList<Integer>();
        for (int i = 1; i <= 1000000; i++) {
            intList.add(i);
        }

        TimeRecorder recorder = new TimeRecorder();

        recorder.start();
        intList.stream().forEach(i -> {
            i.intValue();
            i.intValue();
            i.toString();

            i.intValue();
            i.intValue();
            i.toString();
        });
        recorder.end();
        System.out.print("Stream iterator:");
        System.out.println(recorder.getDuration());

        recorder.start();
        intList.parallelStream().forEach(i -> {
            i.intValue();
            i.intValue();
            i.toString();

            i.intValue();
            i.intValue();
            i.toString();
        });
        recorder.end();
        System.out.print("Parallel Stream iterator:");
        System.out.println(recorder.getDuration());

        recorder.start();
        for (Integer i : intList) {
            i.intValue();
            i.intValue();
            i.toString();

            i.intValue();
            i.intValue();
            i.toString();
        }
        recorder.end();
        System.out.print("Normal iterator:");
        System.out.println(recorder.getDuration());
    }
}


输出如下:

Stream iterator:808

Parallel Stream iterator:313

Normal iterator:377

Stream的适合场景

集合操作超过两个步骤

比如先filter再for each

这时Stream显得优雅简洁,效率也高

任务较重,注重效能,希望并发执行

很容易的就隐式利用了多线程技术。非常好的使用时机。

函数式编程的编码风格里

Stream的设计初衷之一

结语

Lambda,Stream等等新特性使得Java函数式编程更为自然。合适的环境下非常值得合理使用。但是请记住Stream的创建以及传输也有损耗,特别简单的场景可能传统的For Loop更为适合。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: