java8的λ(lambda)表达式与Stream

一、λ(lambda)表达式学习

Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正在将自己变的更高级,更人性化。--------可以这么说lambda表达式其实就是实现SAM接口的语法糖。–引用其他博主

函数式编程:“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。jdk1.8提供了一个@FunctionalInterface注解来定义函数式接口,如果我们定义的接口不符合函数式的规范便会报错。
@FunctionalInterface
public interface Test {
	//只有一个抽象方法
    public void helloWorld(String y);
}
//方法体自己搞 -> λ用法
Test t = y -> System.out.println("HelloWorld!!!"+y);
玩一玩搞一搞
1、线程

大家都爱拿线程举例子:
普通创建一个线程:

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("这是个线程");
            }
        });
        //启动线程
        thread.start();

λ用法:

Thread thread1 = new Thread(() -> System.out.println("这是个线程"));
        thread1.start();
2、排序(大家都来拿它举例子)

普通玩法:

List<String> list = Arrays.asList(new String[] {"1","103","201","3","204","32","13"});
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return  o1.compareTo(o2);
            }
        });
        System.out.println(list.toString());

//执行结果(附带上一些String排序的小知识)
[1, 103, 13, 201, 204, 3, 32]

λ玩法:

 List<String> list = Arrays.asList(new String[] {"1","103","201","3","204","32","13"});
        /*Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return  o1.compareTo(o2);
            }
        });*/
        Collections.sort(list,(string1,string2) -> string1.compareTo(string2));
        System.out.println(list.toString());
//执行结果:
[1, 103, 13, 201, 204, 3, 32]

执行效率分析:

根据排序进行了如下效率分析:

    public static void main(String[] args) {
        List<String> list = Arrays.asList(new String[] {"1","103","201","3","204","32","13","103","201","3","204","32","13","103","201","3","204","32","13","103","201","3","204","32","13","103","201","3","204","32","13","103","201","3","204","32","13","103","201","3","204","32","13","103","201","3","204","32","13","103","201","3","204","32","13"});
        //执行效率分析
        for(int i=1;i<=100;i++){
            long startTime = System.currentTimeMillis();
            for(int j=1;j<=10000;j++){
                Collections.sort(list, new Comparator<String>() {
                    @Override
                    public int compare(String o1, String o2) {
                        return  o1.compareTo(o2);
                    }
                });
            }
            long endTime = System.currentTimeMillis();
            System.out.println("第"+i+"次普通排序执行时间:"+(endTime-startTime));
            startTime = System.currentTimeMillis();
            for(int j=1;j<=10000;j++){
                Collections.sort(list,(string1,string2) -> string1.compareTo(string2));
            }
            endTime = System.currentTimeMillis();
            System.out.println("第"+i+"次lambda排序执行时间:"+(endTime-startTime));

        }
    }

执行了100次,取中间20个做分析:

第40次普通排序执行时间:5
第40次lambda排序执行时间:6
第41次普通排序执行时间:6
第41次lambda排序执行时间:5
第42次普通排序执行时间:6
第42次lambda排序执行时间:6
第43次普通排序执行时间:5
第43次lambda排序执行时间:7
第44次普通排序执行时间:6
第44次lambda排序执行时间:6
第45次普通排序执行时间:6
第45次lambda排序执行时间:8
第46次普通排序执行时间:6
第46次lambda排序执行时间:6
第47次普通排序执行时间:11
第47次lambda排序执行时间:7
第48次普通排序执行时间:6
第48次lambda排序执行时间:17
第49次普通排序执行时间:6
第49次lambda排序执行时间:9
第50次普通排序执行时间:7
第50次lambda排序执行时间:7
第51次普通排序执行时间:7
第51次lambda排序执行时间:10
第52次普通排序执行时间:9
第52次lambda排序执行时间:7
第53次普通排序执行时间:8
第53次lambda排序执行时间:7
第54次普通排序执行时间:6
第54次lambda排序执行时间:7
第55次普通排序执行时间:7
第55次lambda排序执行时间:6
第56次普通排序执行时间:8
第56次lambda排序执行时间:8
第57次普通排序执行时间:8
第57次lambda排序执行时间:9
第58次普通排序执行时间:9
第58次lambda排序执行时间:17
第59次普通排序执行时间:8
第59次lambda排序执行时间:10

其中:λ>普通为10次,普通>λ为5次,相等为5次
可能力度不够,将10000调整为100000看看

第40次普通排序执行时间:54
第40次lambda排序执行时间:52
第41次普通排序执行时间:53
第41次lambda排序执行时间:55
第42次普通排序执行时间:52
第42次lambda排序执行时间:52
第43次普通排序执行时间:53
第43次lambda排序执行时间:55
第44次普通排序执行时间:55
第44次lambda排序执行时间:55
第45次普通排序执行时间:58
第45次lambda排序执行时间:59
第46次普通排序执行时间:53
第46次lambda排序执行时间:53
第47次普通排序执行时间:52
第47次lambda排序执行时间:53
第48次普通排序执行时间:57
第48次lambda排序执行时间:55
第49次普通排序执行时间:52
第49次lambda排序执行时间:63
第50次普通排序执行时间:55
第50次lambda排序执行时间:54
第51次普通排序执行时间:51
第51次lambda排序执行时间:54
第52次普通排序执行时间:53
第52次lambda排序执行时间:54
第53次普通排序执行时间:52
第53次lambda排序执行时间:57
第54次普通排序执行时间:61
第54次lambda排序执行时间:60
第55次普通排序执行时间:54
第55次lambda排序执行时间:61
第56次普通排序执行时间:51
第56次lambda排序执行时间:53
第57次普通排序执行时间:54
第57次lambda排序执行时间:59
第58次普通排序执行时间:59
第58次lambda排序执行时间:62
第59次普通排序执行时间:54
第59次lambda排序执行时间:60

将100000调整为1000000看看

第40次普通排序执行时间:564
第40次lambda排序执行时间:586
第41次普通排序执行时间:576
第41次lambda排序执行时间:557
第42次普通排序执行时间:569
第42次lambda排序执行时间:586
第43次普通排序执行时间:599
第43次lambda排序执行时间:582
第44次普通排序执行时间:559
第44次lambda排序执行时间:572
第45次普通排序执行时间:580
第45次lambda排序执行时间:588
第46次普通排序执行时间:578
第46次lambda排序执行时间:572
第47次普通排序执行时间:580
第47次lambda排序执行时间:557
第48次普通排序执行时间:579
第48次lambda排序执行时间:620
第49次普通排序执行时间:582
第49次lambda排序执行时间:606
第50次普通排序执行时间:613
第50次lambda排序执行时间:624
第51次普通排序执行时间:583
第51次lambda排序执行时间:581
第52次普通排序执行时间:653
第52次lambda排序执行时间:683
第53次普通排序执行时间:688
第53次lambda排序执行时间:699
第54次普通排序执行时间:690
第54次lambda排序执行时间:693
第55次普通排序执行时间:573
第55次lambda排序执行时间:707
第56次普通排序执行时间:785
第56次lambda排序执行时间:563
第57次普通排序执行时间:593
第57次lambda排序执行时间:597
第58次普通排序执行时间:561
第58次lambda排序执行时间:568
第59次普通排序执行时间:688
第59次lambda排序执行时间:585

差别其实没有太大

二、Stream (原理很深奥,用法很简单)

同样是,我们先学会骑自行车,再去研究轮子,再去造轮子

Stream是Java 8中的一个大的改进。Stream的功能是,支持集合的各种操作,比如filter, sum, max, min, average, map, reduce等等。
它可以:增强集合操作
拥抱函数式编程
充分利用Lambda
执行效率的提高 - 透明支持多线程集合操作

玩一玩搞一搞

首先new了一个学生实体类:

public class Student implements Serializable {
    private long id;
    private String name;
    private String sex;
    private int age;
    private String remore;
    //setter And getter方法
}

然后写了一个setListValue方法来给list赋值

    public static void setListValue(List list){
        for(int i=0;i<1000;i++){
            Student student = new Student();
            student.setAge(10+(i/100));
            student.setId(i);
            student.setName("啊"+i);
            student.setRemore("这是个"+i);
            student.setSex(String.valueOf(i%2));
            list.add(student);
        }
    }
一、使用stream来进行排序

根据id正序正序

        //根据id正序
        list.stream().sorted(Comparator.comparing(Student::getId)).collect(Collectors.toList());

根据id正序逆序

list.stream().sorted(Comparator.comparing(Student::getId).reversed()).collect(Collectors.toList());
拿出实体复合条件的属性并吧该属性单独放到一个容器中
        List<String> oldMan = list.stream().filter(student -> student.getAge() > 18).map(Student::getName).collect(Collectors.toList());
        System.out.println(oldMan);
filter做过滤
        list.stream().filter(student -> student.getAge()>18).collect(Collectors.toList()).forEach(student -> {
            //a="qwer";
            student.setName("呦呦呦");
        });
forech循环
        List<String> addF=new ArrayList<>();
        //得到其中所有的Name属性并赋值给addF
        addF=list.stream().map(Student::getName).collect(Collectors.toList());
        addF.stream().forEach(name ->{
            //做一些逻辑
            if(name.contains("啊")){
               
            }
        });
注意:

forech循环这个里面有点限制,在这个forech循环外命名的变量没有办法在forech循环里面使用,若想使用,必须定义成常量

性能问题分析:

首先简单写了一个测试性能的代码,如下:

        for(int i =1;i<100;i++) {
            List<Student> list = new ArrayList<Student>();
            setListValue(list);
            long startTime = System.currentTimeMillis();
            //用for循环遍历
            for (Student student : list) {
                String[] strings = student.getName().split("1");
                String str = "start";
                for (int j = 0; j < 1000; j++) {
                    str = str + "hello";
                }
            }
            long endTime = System.currentTimeMillis();
            System.out.println("第"+i+"次用for循环遍历耗时》》》" + (endTime - startTime));
            startTime = System.currentTimeMillis();
            //用迭代器遍历
            Iterator<Student> iterator = list.iterator();
            while (iterator.hasNext()) {
                String[] strings = iterator.next().getName().split("1");
                String str = "start";
                for (int j = 0; j < 1000; j++) {
                    str = str + "hello";
                }
            }
            endTime = System.currentTimeMillis();
            System.out.println("第"+i+"次用迭代器遍历耗时》》》" + (endTime - startTime));
            startTime = System.currentTimeMillis();
            //用stream遍历
            list.stream().forEach(student -> {
                String[] strings = student.getName().split("1");
                String str = "start";
                for (int j = 0; j < 1000; j++) {
                    str = str + "hello";
                }
            });
            endTime = System.currentTimeMillis();
            System.out.println("第"+i+"次用stream遍历耗时》》》" + (endTime - startTime));
            startTime = System.currentTimeMillis();
            //用parallelStream来遍历
            list.parallelStream().forEach(student -> {
                String[] strings = student.getName().split("1");
                String str = "start";
                for (int j = 0; j < 1000; j++) {
                    str = str + "hello";
                }
            });
            endTime = System.currentTimeMillis();
            System.out.println("第"+i+"次用parallelStream来遍历耗时》》》" + (endTime - startTime));
        }

输出结果如下:

  • 我自己电脑(物理cpu个数:1个,核数:双核)

第20次用迭代器遍历耗时》》》1173
第20次用stream遍历耗时》》》1113
第20次用parallelStream来遍历耗时》》》1103
第21次用for循环遍历耗时》》》1270
第21次用迭代器遍历耗时》》》1300
第21次用stream遍历耗时》》》1383
第21次用parallelStream来遍历耗时》》》1065
第22次用for循环遍历耗时》》》1126
第22次用迭代器遍历耗时》》》1157
第22次用stream遍历耗时》》》1249
第22次用parallelStream来遍历耗时》》》1105
第23次用for循环遍历耗时》》》1219
第23次用迭代器遍历耗时》》》1203
第23次用stream遍历耗时》》》1122
第23次用parallelStream来遍历耗时》》》1077
第24次用for循环遍历耗时》》》1319
第24次用迭代器遍历耗时》》》1248
第24次用stream遍历耗时》》》1401
第24次用parallelStream来遍历耗时》》》1157
第25次用for循环遍历耗时》》》1197
第25次用迭代器遍历耗时》》》1215
第25次用stream遍历耗时》》》1426
第25次用parallelStream来遍历耗时》》》1095
第26次用for循环遍历耗时》》》1244
第26次用迭代器遍历耗时》》》1302
第26次用stream遍历耗时》》》1106
第26次用parallelStream来遍历耗时》》》1040
第27次用for循环遍历耗时》》》1402
第27次用迭代器遍历耗时》》》1275
第27次用stream遍历耗时》》》1143
第27次用parallelStream来遍历耗时》》》1092
第28次用for循环遍历耗时》》》1353
第28次用迭代器遍历耗时》》》1390
第28次用stream遍历耗时》》》1361
第28次用parallelStream来遍历耗时》》》1065
第29次用for循环遍历耗时》》》1114
第29次用迭代器遍历耗时》》》1200
第29次用stream遍历耗时》》》1486
第29次用parallelStream来遍历耗时》》》1114
第30次用for循环遍历耗时》》》1525
第30次用迭代器遍历耗时》》》1417
第30次用stream遍历耗时》》》1214
第30次用parallelStream来遍历耗时》》》1049

  • 性能好点的服务器(物理cpu个数:1个,核数:4核,逻辑cpu个数:8)

第50次用for循环遍历耗时》》》768
第50次用迭代器遍历耗时》》》768
第50次用stream遍历耗时》》》763
第50次用parallelStream来遍历耗时》》》167
第51次用for循环遍历耗时》》》762
第51次用迭代器遍历耗时》》》760
第51次用stream遍历耗时》》》751
第51次用parallelStream来遍历耗时》》》168
第52次用for循环遍历耗时》》》773
第52次用迭代器遍历耗时》》》764
第52次用stream遍历耗时》》》770
第52次用parallelStream来遍历耗时》》》153
第53次用for循环遍历耗时》》》767
第53次用迭代器遍历耗时》》》765
第53次用stream遍历耗时》》》764
第53次用parallelStream来遍历耗时》》》159
第54次用for循环遍历耗时》》》756
第54次用迭代器遍历耗时》》》760
第54次用stream遍历耗时》》》767
第54次用parallelStream来遍历耗时》》》160
第55次用for循环遍历耗时》》》765
第55次用迭代器遍历耗时》》》771
第55次用stream遍历耗时》》》768
第55次用parallelStream来遍历耗时》》》165
第56次用for循环遍历耗时》》》757
第56次用迭代器遍历耗时》》》754
第56次用stream遍历耗时》》》758
第56次用parallelStream来遍历耗时》》》156
第57次用for循环遍历耗时》》》763
第57次用迭代器遍历耗时》》》761
第57次用stream遍历耗时》》》761
第57次用parallelStream来遍历耗时》》》164
第58次用for循环遍历耗时》》》763
第58次用迭代器遍历耗时》》》760
第58次用stream遍历耗时》》》767
第58次用parallelStream来遍历耗时》》》171
第59次用for循环遍历耗时》》》763
第59次用迭代器遍历耗时》》》828
第59次用stream遍历耗时》》》768
第59次用parallelStream来遍历耗时》》》161
第60次用for循环遍历耗时》》》770
第60次用迭代器遍历耗时》》》770
第60次用stream遍历耗时》》》764
第60次用parallelStream来遍历耗时》》》159

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值