Java教程

函数式编程 jdk10中stream流里面peek方法

本文主要是介绍函数式编程 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方法没有执行

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<Demo> demos  = new ArrayList<Demo>();

        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对象被修改了。输出

 

 

 

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

 

 

 

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

这篇关于函数式编程 jdk10中stream流里面peek方法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!