java8-使用场景


双冒号的使用

双冒号运算符在Java 8中被用作方法引用,方法引用是与 lambda 表达式相关的一个重要特性。它提供了一种不执行方法的方法。为此,方法引用需要由兼容的函数接口组成的目标类型上下文。

使用lambda表达式会创建匿名方法, 但有时候需要使用一个lambda表达式只调用一个已经存在的方法(不做其它), 所以这才有了方法引用!

以下是Java 8中方法引用的一些语法:
  静态方法引用语法:classname::methodname 例如:Person::getAge 

    Comparator.comparingDouble(GovsProductCatBo::getShowSn)

  对象的实例方法引用语法:instancename::methodname 例如:System.out::println
  对象的超类方法引用语法: super::methodname
  类构造器引用语法: classname::new 例如:ArrayList::new
  数组构造器引用语法: typename[]::new 例如: String[]:new

使用场景1-list遍历

     List list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        // 直接打印
        list.forEach(System.out::println);

        // 取值分别操作
        list.forEach(i -> {
            System.out.println(i * 3);
        });

执行结果:

使用场景2-list遍历并改变list的内容

        List list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);

        // 可改变对象
        list.stream().map((i) -> i * 3).forEach(System.out::println);

        // 不可改变元有对象
        list.forEach(i -> i = i * 3);
        list.forEach(System.out::println);

使用场景3-函数式接口

所有的Lambda的类型都是一个接口,而Lambda表达式本身,也就是”那段代码“,需要是这个接口的实现

注意:能够接收Lambda表达式的参数类型,是一个只包含一个方法的接口。只包含一个方法的接口称之为“函数接口”。

所以这个接口最好加上 @FunctionalInterface, 这样别人就无法在里面添加新的接口函数了

e.g

1.先声明一个接口 

2.编写lambda和调用

        ILhwTestLambda lhwTestLambda = (s) -> System.out.println(s);
        lhwTestLambda.saySomething("111");

3.结果:控制台打印 111

使用场景4-使用reduce进行数组运算,得到一个值

        // 字符串连接,concat = "ABCD"
        String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
        // 求最小值,minValue = -3.0
        double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
        // 求和,sumValue = 11, 有起始值
        int sumValue = Stream.of(1, 2, 3, 4).reduce(1, Integer::sum);
        // 求和,sumValue = 10, 无起始值
        sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
        // 过滤,字符串连接,concat = "ace"
        concat = Stream.of("a", "B", "c", "D", "e", "F").filter(x -> x.compareTo("Z") > 0).reduce("", String::concat);

使用场景5-使用collect进行数组运算,得到一个新数组

        //Original List : [abc, eqwr, bcd, qb, ehdc, jk], filtered list : [abc, eqwr, bcd, ehdc]
        List strList = Arrays.asList("abc", "eqwr", "bcd", "qb" , "ehdc", "jk");
        List filtered = strList.stream().filter(x -> x.length()> 2).collect(Collectors.toList());
        System.out.printf("Original List : %s, filtered list : %s %n", strList, filtered);

        //filtered list : ABC, EQWR, BCD, QB, EHDC, JK
        List strList2 = Arrays.asList("abc", "eqwr", "bcd", "qb" , "ehdc", "jk");
        String collect = strList2.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));
        System.out.printf("filtered list : %s %n",  collect);

        //Original List : [9, 10, 3, 4, 7, 3, 4],  Square Without duplicates : [81, 100, 9, 16, 49]
        List numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4);
        List distinct = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
        System.out.printf("Original List : %s,  Square Without duplicates : %s %n", numbers, distinct);

使用场景6-进行数组运算,计算最大、最小、和、均值

        //Highest prime number in List : 29
        //Lowest prime number in List : 2
        //Sum of all prime numbers : 129
        //Average of all prime numbers : 12.9
        List primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);
        IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();
        System.out.println("Highest prime number in List : " + stats.getMax());
        System.out.println("Lowest prime number in List : " + stats.getMin());
        System.out.println("Sum of all prime numbers : " + stats.getSum());
        System.out.println("Average of all prime numbers : " + stats.getAverage());

使用场景7-对null值的判断处理

1.存在则执行方法

        GetProductAchievementListVo productAchievementListVo = new GetProductAchievementListVo();
        Optional op = Optional.ofNullable(productAchievementListVo);
        op.ifPresent(System.out::println);//会打印出来

        productAchievementListVo = null;
        Optional op1 = Optional.ofNullable(productAchievementListVo);
        op1.ifPresent(System.out::println);//不会打印出来

2.存在则返回自己,无则返回新内容

        String str0 = "我是原配";
        Optional op1 = Optional.ofNullable(str0);
        str0 = op1.orElse("我是替代品");
        System.out.println(str0);--我是原配

        String str = null;
        Optional op2 = Optional.ofNullable(str);
        str = op2.orElse("我是替代品");
        System.out.println(str);--我是替代品

3.存在则返回自己,无则由函数返回

        String str0 = "我是原配";
        Optional op1 = Optional.ofNullable(str0);
        str0 = op1.orElseGet(() -> retTest());
        System.out.println(str0);--我是原配

        String str = null;
        Optional op2 = Optional.ofNullable(str);
        str = op2.orElseGet(() -> retTest());
        System.out.println(str);--我是替代品


    public String retTest() {
    return "我是替代品";
    }

4.连续的null判断

入参:

{
  "fileName": "1",
  "fileSort": "2",
  "prodCatCode": "3",
  "prodOrgCode": "4",
  "productName": "5"
}

代码过程

        Optional op1 = Optional.ofNullable(productAchievementListVo);
        String str = op1.map(fileName -> productAchievementListVo.getFileName())
            .map(fileSort -> productAchievementListVo.getFileSort())
            .orElse(null);
        System.out.println(str);//返回值:2

逻辑说明:

1.先判断getFileName是不是为null,为null直接返回orElse的值。

2.若不是,继续判断getFileSort,不为空。结束map返回getFileSort的值。为null 直接返回orElse的值。

getFileName