lambda 流 peek java_jdk10中stream流里面peek方法注意点

最近在我的课程里面SpringBoot2.0不容错过的新特性 WebFlux响应式编程里面,有学员提出了以下问题,在jdk10里面代码没有执行(课程中stream流是用jdk8演示的)

代码:public class LambdaDemo {

public static void main(String[] args) {

IntStream.range(1,10).peek(LambdaDemo::debug).count();

}

public static void debug(int i) {

System.out.println(Thread.currentThread().getName() + " " + " debug " + i);

try {

TimeUnit.MILLISECONDS.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

jdk10运行不会产生结果,8就没有问题

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

我第一个感觉是不可能,觉得是学员搞错了,理论上jdk不可能不兼容的,让学员检查代码和环境。学员检查之后说确实如此,于是我在jdk10下运行测试,确实如学员所说,peek的日志没有打印出来。

看来即使工作校验再丰富的人,也会因为想当然犯错误。于是我翻了以下jdk10的api说明,最终发现不是代码没有执行,而是jdk10下调用count方法的时候,peek方法没有执行!

jdk说明:

AAffA0nNPuCLAAAAAElFTkSuQmCC

api上说了,count方法的时候,peek不会执行。所以上面代码不是没有执行,而是peek方法没有执行public class LambdaDemo {

public static void main(String[] args) {

long count = IntStream.range(1,10).peek(LambdaDemo::debug).count();

System.out.println("count=" + count);

}

public static void debug(int i) {

System.out.println(Thread.currentThread().getName() + " " + " debug " + i);

try {

TimeUnit.MILLISECONDS.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

上面代码里面,可以打印出count=9,但peek日志没有打印(jdk8里面能打印)。需要说明的是,peek方法不是都不会执行,调用count不会执行,调用sum的时候就会执行!

学会技术最重要的学习技术的思想

另外说明一点,我们学习一个新技术,学会api的使用只是其次的,最重要的是学会这种技术的思想。好比你学习了vue,但还是用jquery的思维来写代码,这都是不对的!回到我们的函数式编程里面,函数式编程里面,对象在流操作(函数操作里面)里面,不应该产生任何修改(副作用side-effects),修改对象的时候应该返回新对象。

如下代码,peek中修改了对象,产生了副作用(peek只应该用于debug作用,不应该有修改操作产生副作用)import java.lang.management.ManagementFactory;

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

class Demo{

public  String msg = "初始值";

}

public class LambdaDemo2 {

public static void main(String[] args) {

System.out.println("jdk版本:"+ManagementFactory.getRuntimeMXBean().getVmVersion());

List demos  = new ArrayList();

demos.add(new Demo());

demos.add(new Demo());

// 这里peek中修改了对象,产生了副作用(side-effects)

long count = demos.stream().peek(demo -> demo.msg = "peek中修改了").count();

System.out.println(count);

// jdk8下下面的demo已经改变

// jdk10下没有

demos.stream().forEach(demo -> System.out.println(demo.msg));

}

}

jdk8中,peek方法执行了,demo对象被修改了。输出

AAffA0nNPuCLAAAAAElFTkSuQmCC

而jdk10中,peek没有执行,demo对象没有修改!

AAffA0nNPuCLAAAAAElFTkSuQmCC

所以,函数式编程里面,函数应该是没有副作用的,对象不应该被修改产生副作用(如果要修改应该用map方法),大家一定要用函数式的思想来写函数式的代码!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值