深入浅出理解JAVA 8 Lambda表达式 Stream

JAVA 8 发布于2014年3月19日

JAVA 8新特性 Lambda 表达式 帮助我们开发者 Write less, do more,作为开发者的我们还是有必要详细了解的

作为新特性我们开发者使用应先阅读由Oracle公司发布的官方文档,基本了解Lambda 使用范围

官方文档阅读

我在仔细阅读Oracle发布的官方文档之后,对Lambda表达式有了一些基础的认识,接下来,我带大家一起了解Lambda使用,以及在java虚拟机中实际执行的命令

什么是Lambda表达式?
Lambda 表达式实质是一个可以实现某一接口的匿名内部类的中的方法
Lambda表达式组成部分

  1. 括号包起来的参数 (若参数仅有一个 可省略括号)
  2. 一个箭头 既 (-> 操作符)
  3. 方法体,可以是单个语句,也可以是语句块 (若是单个语句 则可以直接写出结尾不需要; 结束,若为语句块则两边需加入花括号,每局结尾以; 结束)

    参数可以写类型,也可以不写,
    方法可以有返回,也可以无返回,如果是一条语句,结果可以作为默认为返回值,
    如果有多个语句,需要加上return 例如

        List<String> array = Arrays.asList("xiaowang","laowang");
        Collections.sort(array, (str1,str2) -> str1.length() - str2.length() ); Collections.sort(array, (String str1,String str2) -> str1.length() - str2.length() ); Collections.sort(array, (String str1,String str2) -> { System.out.println(str1 + " " +str2); return str1.length() - str2.length(); }); 

基本Lambda表达式实现

        Runnable r = () -> System.out.println("My first Lambda expression");
        new Thread(r).start();

Console:My first Lambda expression

传递一个带参数的Lambda表达式
Interface Consumer< T >
Consumer接口的accept方法就是一个有一个参数并且无返回值的方法,
可以用Lambda表达式来创建Consumer的实例

        Consumer<String> consumer = (x) -> {System.out.println(x);};
                             //(x) -> System.out.println(x);
                             //x -> System.out.println(x);
                    //上面注释两种方法均可运行
        consumer.accept("My second Lambda expression");

Console:My second Lambda expression
Interface Function< T , R>
Function接口的apply方法就是一个有一个参数并且有返回值的方法 T(参数),R(返回值)
那么就可以这样子使用Lambda表达式来创建Function的实例
Function

        Function<Integer, Double> f = i -> i.doubleValue() +0.2 ;
        System.out.println(f.apply(8));

Console:8.2

Lambda表达式 需要先了解JDK 8 中新添加的一个类 java.util.stream

Stream是元素的集合,任何集合都可以转换为Stream:

方法名说明参数返回值
of静态方法 用于初始化Stream可以传入数组或一组数值Stream
filter过滤,流程中某些元素Predicate(使用有一个参数 返回布尔值 过滤符合要求的留在stream流里面)Stream
map返回由函数返回值对应的所有流Function上文提到过Stream
peek返回含有原Stream的所有元素的新Stream,并在下次foreach时执行本次传入的ConsumerConsumer(用的lambda写) 上文提到过Stream
limit截断,从0截取到参数位置(剩余参数个元素)long(小于流的最大长度)Stream
skip抛弃,参数位置直接扔掉(直接抛弃参数个元素)long(小于流的最大长度)Stream
distinct去重复,底层通过hashcode和equal比较,相同的话去除voidvoid
forEach对该流每一个元素进行操作Consumer 上文提到过void

其余的大家可以通过API了解

看完了以上方法,练习一下以上方法的使用

        List<String> list = Arrays.asList("aaa","bbb","a","ccc","aaa");
        // 用Lambda表达式遍历list集合
        list.forEach(e -> System.out.print(e+" "));
        list.forEach(System.out::println);
        //初始化 Stram 
        Stream<String> s = Stream.of("aaa","bbb");
        s.forEach(e -> System.out.println(e+" "));
        /** * 此时 s 对象内已经没有可操作的元素 * 如果继续操作会抛出 java.lang.IllegalStateException * 所以之后都用list.stream()从新获取可读取的Stream集合 */
        //filter 方法
        list.stream().filter(e -> e.startsWith("a")).
        forEach(e -> System.out.println("filter方法匹配开头为a"+e+" "));
        //map方法
        list.stream().map(e -> e.hashCode()).
        forEach(e -> System.out.println("map方法返回hashCode的值"+e));
        //peek方法
        list.stream().peek(e -> System.out.print(e.hashCode())).
        forEach(e -> System.out.println("< - peek方法在调用forEach方法前执行"+e));
        //limit方法
        list.stream().limit(2).forEach(e -> System.out.println("limit截断 现在只有两个元素"+e));
        //skip 方法
        list.stream().skip(2).forEach(e -> System.out.println("skip跳过 跳过了二个元素"+e));
        //distinct 方法
        list.stream().distinct().forEach(e -> System.out.println("distinct 元素中去掉重复值"+e));

Lambda表达式还可以用于GUI的监听事件简写

        JButton jb = new JButton();
        jb.addActionListener(e -> jbClick(e));
        //、可以将代码直接写在jbClick(e),优化代码书写

需要注意的是Lambda表达式只能适用于接口内仅有一个抽象方法的类,若含有多个抽象方法,还是老实的写一个实体类或者匿名内部类把,相信如果大家仔细看完本篇文章会对Lambda表达式有所了解,那么请关注博主把!!
我就是一个还在学习的大学生,如果以上有错误,还请提出,我必定会改正

感谢阅读(关注我哦)

    原文作者:changzhiqiang_
    原文地址: https://blog.csdn.net/crpxnmmafq/article/details/72510314
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞