集合Stream流更改外部值会比迭代器更快吗?
集合Stream流
Stream的优点
- JDK1.8后计入Stream流,给繁琐的遍历、聚合等操作带来便捷,并且因为其并行的特点,非常高效。
函数式接口
- JDK1.8同样带来的还有函数式接口,配合lambda表达式,能够极大程度简化Stream操作代码。
但这也带了一个问题
值作为参数传递给Lambda表达式,类加载器为Lambda表达式建立一个副本,它的代码访问的是这个副本,而不是外部声明的变量。
关于Lambda表达式里面修改外部变量问题
所以我们必须要保证lambda更改的变量的原子性Atomic。
变量的原子性
原子变量最主要的一个特点就是所有的操作都是原子的,synchronized关键字也可以做到对变量的原子操作。只是synchronized的成本相对较高,需要获取锁对象,释放锁对象,如果不能获取到锁,还需要阻塞在阻塞队列上进行等待。而如果单单只是为了解决对变量的原子操作,建议使用原子变量
Java并发编程之原子变量
但这样的话不就没办法展示出并行的特点,在更改外部变量时速度不就慢下来了吗
引起猜想
- 如果没有了并行特点,那Stream和迭代器还有什么区别?
- 毕竟迭代器本来就是一个一个操作不需要原子变量加持,比流遍历还少了一个步骤。
- 那迭代器在执行效率上会不会更高呢?
实验检验
是骡子是马拉上场溜溜就知道了!
测试
-
流操作
首先看一下没了并行特点的Stream能够多长时间执行完操作
private long run(){ Map<String, String> map = new HashMap<>(); AtomicReference<String> str = new AtomicReference<>(""); int max = 10000000; for(int i = 0; i < max; i++){ map.put("key"+i,"value"+i); } long time = System.currentTimeMillis(); map.entrySet().stream().forEach(entry->{ str.set(entry.getKey() + ":" + entry.