• JDK8 新特性 Lambda表达式


    1.java8中Lambda表达式基础语法:

    (x,y) -> {}

    左侧是一个小括号,里面是要实现的抽象方法的参数,有几个参数就写几个参数名,无参可写空括号,无需声明参数类型;

    中间是一个jdk8新定义的箭头符号;

    右侧是一个大括号,在括号内编写抽象方法的实现内容,有参时,可直接使用左侧括号中的对应参数,与正常方法的方法体相同;

    使用方式:实现只有一个抽象方法的接口时会自行匹配到该方法,在箭头左侧编写对应参数个数的参数名,箭头右侧编写方法的实现代码(代码实现为单行时可去掉大括号{})

     示例:

     1     @Test
     2     public void test() {
     3         //输入一个数,与100比较大小
     4 
     5         //实现方式1 匿名内部类:
     6         Comparable<Integer> comparable1 = new Comparable<Integer>() {
     7             @Override
     8             public int compareTo(Integer o) {
     9                 return Integer.compare(o, 100);
    10             }
    11         };
    12         comparable1.compareTo(2);
    13 
    14         //实现方式2 Lambda表达式:实现只有一个抽象方法的Comparable接口时会自行匹配到compareTo方法,在箭头左侧编写对应参数个数的参数名,箭头右侧编写方法的实现代码
    15         Comparable<Integer> comparable2 = (x) -> Integer.compare(x, 100);
    16         comparable2.compareTo(2);
    17     }

    2.Lambda表达式的函数式编程需要函数式接口(有且只有一个抽象方法的接口)的支持,为了防止使用Lambda表达式时都必须手动添加接口,Java8内置了四大核心函数式接口:

    /**
    * Java8内置的四大核心函数式接口
    *
    * Consumer<T> :消费型接口
    * void acept(T t);
    *
    * Supplier<T> :供给型接口
    * T get();
    *
    * Function<T,R> :函数型接口
    * R apply(T t);
    *
    * Predicate<T> :断言型接口
    * boolean test(T t);
    */

     1     public static void main(String[] args) {
     2         //内置函数式接口使用示例
     3 
     4         //消费型接口Consumer,输入一个参数,对其进行打印输出
     5         Consumer<String> consumer = (x) -> System.out.println(x);
     6         //打印字符串
     7         consumer.accept("hehe");
     8 
     9         //供给型接口Supplier,返回指定字符串
    10         Supplier<String> supplier = () -> "Hello world!";
    11         //获取字符串
    12         supplier.get();
    13 
    14         //函数型接口Function,输入字符串,返回字符串长度
    15         Function<String, Integer> function = (x) -> x.length();
    16         //获取字符串长度
    17         function.apply("Hello world!");
    18 
    19         //断言型接口Predicate,输入数字,判断是否大于0
    20         Predicate<Integer> predicate = (x) -> x > 0;
    21         //获取判断结果
    22         predicate.test(10);
    23     }

    除了这四个接口外还有其他多参数的子接口,自行查找。


    3.某些情况下要实现的业务部分已有方法实现,可直接引用该方法,此时可使用Lambda表达式中的方法引用:

    /**
    * 方法引用:若Lambda体中的内容有方法已经实现了,我们可以使用“方法引用”
    * 可以理解为方法引用是lambda表达式的另外一种表达形式
    *
    * 主要有三种语法格式:
    *
    * 对象::实例方法名
    *
    * 类::静态方法名
    *
    * 类::实例方法名
    */
    方法引用注意点:被引用的方法的参数和返回值必须和要实现的抽象方法
    的参数和返回值一致
    1         //引用out对象的打印输出方法作为Consumer接口accept方法的具体实现
    2         Consumer<String> consumer1 = System.out::println;
    3         consumer1.accept("hehe");
    4         
    5         //lambda表达式常用方式
    6         BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
    7         //方法引用:类::实例方法(方法传入参数是两个参数,且第一个参数作为方法调用对象,第二个参数作为调用的方法的参数)
    8         BiPredicate<String, String> bp2 = String::equals;

     4.构造器引用:通过函数式接口实例化类时可进行构造器引用

    注意点:引用到的是与函数式接口中的方法参数个数及类型相同的构造器

    1         //lambda表达式常用方式
    2         Supplier<Passenger> supplier1 = () -> new Passenger();
    3         //构造器引用:通过类型推断,引用无参构造器
    4         Supplier<Passenger> supplier2 = Passenger::new;
    5       
    6         //lambda表达式常用方式
    7         BiFunction<String, String, Passenger> function1 = (x, y) -> new Passenger(x, y);
    8         //构造器引用:通过类型推断,引用有两个String参数的构造器
    9         BiFunction<String, String, Passenger> function2 = Passenger::new;

    5.数组引用:

    1         //lambda表达式常用方式
    2         Function<Integer, String[]> fun1 = (x) -> new String[x];
    3         String[] strs1 = fun1.apply(10);
    4         //数组引用
    5         Function<Integer, String[]> fun2 = String[]::new;
    6         String[] strs2 = fun2.apply(10);

    6.Stream流的应用

    Stream的使用步骤:
    1 创建Stream对象
    2 执行中间操作
    3 执行终止操作

    1)Stream对象的创建方式:

     1     /**
     2      * Stream的使用:
     3      * 1 创建Stream对象
     4      * 2 中间操作
     5      * 3 终止操作
     6      */
     7     public static void main(String[] args) {
     8         //stream对象获取方式:
     9         String[] strings = {"1", "2", "3", "4"};
    10         
    11         //方式1:数组获取stream对象
    12         Stream<String> stream1 = Arrays.stream(strings);
    13         
    14         //方式2:集合获取stream对象
    15         List<String> list = Arrays.asList(strings);
    16         Stream<String> stream2 = list.stream();
    17         
    18         //方式3:Stream静态方法of获取stream对象
    19         Stream<String> stream3 = Stream.of(strings);
    20         
    21         //方式4:创建无限流(seed起始值,重复无限次执行的方法)
    22         //无限流1:迭代
    23         Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
    24         //无限流2:生成
    25         Stream<Double> stream5 = Stream.generate(() -> Math.random());
    26     }

    2)Stream常用中间操作方法:

     1         //Stream常用方法(链式方法,从上往下执行,下一个方法进行处理的对象是上一个方法处理后的结果)
     2         Arrays.stream(new Integer[]{1, 63, 3, 7, 11, 54, 34})
     3                 //过滤器,传入一个Predicate断言型接口实现,Stream会进行内部遍历,将保留断言返回true的元素(此处过滤保留值大于4的元素)
     4                 .filter(x -> x > 4)
     5                 //截断流,只获取前n个元素(此处获取满足过滤器条件的前2个元素)
     6                 .limit(5)
     7                 //跳过元素,跳过前n个元素,获取后面的元素,若流中的元素不足n个,则返回一个空流,与limit互补(此处取除第一个元素外的元素)
     8                 .skip(1)
     9                 //映射,对流内元素进行处理,可以是转换类型、获取属性值等等,传入一个Function函数型接口实现(此处对流内元素全部加5)
    10                 .map(x -> x + 5)
    11                 //自然排序(按照Comparable默认排序,此处为Integer从小到大排序)
    12                 .sorted()
    13                 //定制排序(按照Comparator自定义排序,此处处理为Integer从大到小排序)
    14                 .sorted((x, y) -> -Integer.compare(x, y))
    15                 //终止操作,遍历流内元素,传入一个Consumer消费型接口实现(此处简单对流内元素进行打印输出)
    16                 .forEach(System.out::println);

    3)Stream常用终止操作方法:

     1         //终止操作
     2         Integer[] integers = {1, 63, 3, 7, 11, 54, 34};
     3         List<Integer> list = Arrays.asList(integers);
     4 
     5         //匹配所有元素,传入一个Predicate断言型接口实现,当所有元素都满足条件时返回true,否则返回false(此处判断元素是否全部大于0)
     6         boolean b1 = list.stream().allMatch(x -> x > 0);
     7 
     8         //匹配元素,传入一个Predicate断言型接口实现,当有至少一个元素满足条件时返回true,否则返回false(此处判断元素是否全部大于0)
     9         boolean b2 = list.stream().anyMatch(x -> x > 0);
    10 
    11         //无匹配元素,传入一个Predicate断言型接口实现,没有元素满足条件时返回true,否则返回false(此处判断元素是否全部大于0)
    12         boolean b3 = list.stream().noneMatch(x -> x > 0);
    13 
    14         //匹配第一个元素
    15         Optional<Integer> o4 = list.stream().findFirst();
    16 
    17         //匹配任意一个元素
    18         Optional<Integer> o5 = list.stream().findAny();
    19 
    20         //获取流中元素个数
    21         long l6 = list.stream().count();
    22 
    23         //获取流中满足条件的最小值
    24         Optional<Integer> min = list.stream().min(Integer::compare);
    25         System.out.println("min:" + min.get());
    26 
    27         //获取流中满足条件的最大值
    28         Optional<Integer> max = list.stream().max(Integer::compare);
    29         System.out.println("max:" + max.get());
    30 
    31         //归约(将identity作为起始x,第一个元素作为y,计算结果再作为x与下一个元素进行计算,得出计算结果)
    32         Integer reduce = list.stream().reduce(0, (x, y) -> x + y);
    33         //归约(未设置起始x,因此有可能空指针,因此返回类型为Optional)
    34         Optional<Integer> reduce1 = list.stream().reduce(Integer::sum);
    35 
    36         //收集(将流转换为其他形式,接受一个Collector接口实现,用于给Stream中元素做汇总的方法)
    37         List<Integer> collect = list.stream().collect(Collectors.toList());
    38         //转为hashset
    39         HashSet<Integer> collect1 = list.stream().collect(Collectors.toCollection(HashSet::new));
    40         //取平均值
    41         Double collect2 = list.stream().collect(Collectors.averagingInt((x) -> x));
    42         System.out.println("avg:" + collect2);
    43         //求和
    44         Double collect3 = list.stream().collect(Collectors.summingDouble(x -> x));
    45         System.out.println("sum:" + collect3);
    待续。。。


  • 相关阅读:
    Silverlight 程序启动
    在RHEL 下安装PostgreSQL
    在x64 Linux上安装PostGIS
    Datalist或Repeater里点击某列内容将放到文本框中以便编辑,文本框失去焦点后信息即可修改成功
    javascript“设为首页”与“加入收藏”兼容多浏览器代码
    百度地图api 3D图层添加 代码
    百度地图api 开发日志 范围加载
    CLR via C# 第一章 (1)
    首個字母排序
    内存管理
  • 原文地址:https://www.cnblogs.com/new-life/p/11121599.html
Copyright © 2020-2023  润新知