lambda流peekjava_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就没有问题
我第⼀个感觉是不可能,觉得是学员搞错了,理论上jdk不可能不兼容的,让学员检查代码和环境。学员检查之后说确实如此,于是我在
jdk10下运⾏测试,确实如学员所说,peek的⽇志没有打印出来。
看来即使⼯作校验再丰富的⼈,也会因为想当然犯错误。于是我翻了以下jdk10的api说明,最终发现不是代码没有执⾏,⽽是jdk10下调⽤count⽅法的时候,peek⽅法没有执⾏!
jdk说明:
api上说了,count⽅法的时候,peek不会执⾏。所以上⾯代码不是没有执⾏,⽽是peek⽅法没有执⾏p
ublic 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版本:"+RuntimeMXBean().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已经改变
java stream// jdk10下没有
demos.stream().forEach(demo -> System.out.println(demo.msg));
}
}
jdk8中,peek⽅法执⾏了,demo对象被修改了。输出
⽽jdk10中,peek没有执⾏,demo对象没有修改!
所以,函数式编程⾥⾯,函数应该是没有副作⽤的,对象不应该被修改产⽣副作⽤(如果要修改应该⽤map⽅法),⼤家⼀定要⽤函数式的思想来写函数式的代码!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。