后端开发

【十】Java8新特性

2018-05-28  本文已影响0人  吴里庆庆

一、主要内容

1.1 Lambda表达式

注:不支持Lambda表达式可参考https://blog.csdn.net/weixin_39800144/article/details/78500449?locationNum=8&fps=1进行设置。

1.1.1 Lambda表达式语法

/*
 * 一、Lambda 表达式的基础语法:Java8中引入了一个新的操作符 "->" 该操作符称为箭头操作符或 Lambda 操作符
 *                          箭头操作符将 Lambda 表达式拆分成两部分:
 * 
 * 左侧:Lambda 表达式的参数列表
 * 右侧:Lambda 表达式中所需执行的功能, 即 Lambda 体
 * 
 * 语法格式一:无参数,无返回值
 *      () -> System.out.println("Hello Lambda!");
 * 
 * 语法格式二:有一个参数,并且无返回值
 *      (x) -> System.out.println(x)
 * 
 * 语法格式三:若只有一个参数,小括号可以省略不写
 *      x -> System.out.println(x)
 * 
 * 语法格式四:有两个以上的参数,有返回值,并且 Lambda 体中有多条语句
 *      Comparator<Integer> com = (x, y) -> {
 *          System.out.println("函数式接口");
 *          return Integer.compare(x, y);
 *      };
 *
 * 语法格式五:若 Lambda 体中只有一条语句, return 和 大括号都可以省略不写
 *      Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
 * 
 * 语法格式六:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
 *      (Integer x, Integer y) -> Integer.compare(x, y);
 * 
 * 上联:左右遇一括号省
 * 下联:左侧推断类型省
 * 横批:能省则省
 * 
 * 二、Lambda 表达式需要“函数式接口”的支持
 * 函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。 可以使用注解 @FunctionalInterface 修饰
 *           可以检查是否是函数式接口
 */
 //Lambda 表达式
    @Test
    public void test6(){
        List<Employee> list = filterEmployee(emps, (e) -> e.getAge() <= 35);
        list.forEach(System.out::println);

        System.out.println("------------------------------------------");

        List<Employee> list2 = filterEmployee(emps, (e) -> e.getSalary() >= 5000);
        list2.forEach(System.out::println);
    }

1.2 四大内置核心函数式接口

Consumer<T> : 消费型接口
   void accept(T t);
Supplier<T> : 供给型接口
        T get(); 
  Function<T, R> : 函数型接口
        R apply(T t);
 Predicate<T> : 断言型接口
        boolean test(T t);

1.3方法引用与构造器引用

/*
 * 一、方法引用:若 Lambda 体中的功能,已经有方法提供了实现,可以使用方法引用
 *            (可以将方法引用理解为 Lambda 表达式的另外一种表现形式)
 * 
 * 1. 对象的引用 :: 实例方法名
 * 
 * 2. 类名 :: 静态方法名
 * 
 * 3. 类名 :: 实例方法名
 * 
 * 注意:
 *   ①方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!
 *   ②若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName
 * 
 * 二、构造器引用 :构造器的参数列表,需要与函数式接口中参数列表保持一致!
 * 
 * 1. 类名 :: new
 * 
 * 三、数组引用
 * 
 *  类型[] :: new;
 * 
 * 
 */

1.4 Stream API

    //Stream API
    @Test
    public void test7(){
        emps.stream()
                .filter((e) -> e.getAge() <= 35)
                .forEach(System.out::println);

        System.out.println("----------------------------------------------");

        emps.stream()
                .map(Employee::getName)
                .limit(3)
                .sorted()
                .forEach(System.out::println);
    }

2 Stream

注:此节前面几小节还在整理中....

2.5 查找与匹配

测试集合:

List<Employee> emps = Arrays.asList(
            new Employee(102, "李四", 59, 100.00),
            new Employee(101, "张三", 18, 200.00),
            new Employee(103, "王五", 28, 100.00),
            new Employee(104, "赵六", 8, 150.00),
            new Employee(104, "赵六", 28, 200.00),
            new Employee(105, "田七", 38, 150.00)
    );
public void test1() {//查找与匹配
        //排序
        emps.stream().sorted(Comparator.comparingDouble(Employee::getSalary))
                .forEach(System.out::println);
        System.out.println("-------------------------------1---------------------");
        //找到最有钱的员工
        Optional<Employee> one = emps.stream()//.sorted((x,y)->Double.compare(x.getSalary(),y.getSalary()))
                .max(Comparator.comparingDouble(Employee::getSalary));
        System.out.println(one.get());
        System.out.println("-------------------------------2---------------------");
        //找到最穷的员工的工资是多少
        Optional<Double> min = emps.stream().map(Employee::getSalary).min(Double::compare);
        System.out.println(min.get());
        System.out.println("-------------------------------3---------------------");
        //个数
        long count = emps.stream().filter((x) -> x.getSalary() > 50).count();
        System.out.println(count);
    }

2.6 归约与收集

 @Test
    public void test2() {//归约
        System.out.println("----------------------(1)测试归约---------------------");
        List<Integer> list = Arrays.asList(1, 2, 3);
        Integer a = 1;
        Integer sum = list.stream().reduce(a, (x, y) -> x + y);
       /* Optional<Integer> reduce = list.stream().reduce((x, y) -> x + y);
        System.out.println(reduce.get());*/
        //先把a作为x,再从集合中取出第一个元素1作为y,
        // 把它们相加的结果再作为x,再从集合中取出第2个元素作为y依次类推相加的结果就是sum.
        System.out.println(sum);
        System.out.println("----------------------(2)测试员工工资总和---------------------");
        Optional<Double> salarys = emps.stream().map(Employee::getSalary).reduce(Double::sum);
        //为什么这里返回的是Optional?因为员工的工资为空,而上面第一个例子中有个起始值a所以它不为空
        System.out.println(salarys.get());
    }

 @Test
    public void test3() {//收集
        System.out.println("----------------------(1)测试收集---------------------");
        //放到list中
        List<String> collect = emps.stream().map(Employee::getName).collect(Collectors.toList());
        collect.forEach(System.out::println);
        System.out.println("----------------------(2)测试收集set去重---------------------");
        //放到set中 去下重
        Set<String> namesDistinct = emps.stream().map(Employee::getName).collect(Collectors.toSet());
        namesDistinct.forEach(System.out::println);
        //想放哪就放哪
        System.out.println("----------------------(3)测试收集hashset---------------------");
        HashSet<String> hashNames = emps.stream().map(Employee::getName).collect(Collectors.toCollection(HashSet::new));
        hashNames.forEach(System.out::println);
        System.out.println("----------------------(4)测试收集 获取总数和平均值 ---------------------");

        //总数
        Long num = emps.stream().collect(Collectors.counting());
        System.out.println(num);
        //平均值
        Double averageSalary = emps.stream().collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println(averageSalary);
        //工资总和
        Double sumSalary = emps.stream().collect(Collectors.summingDouble(Employee::getSalary));
        System.out.println(sumSalary);
        //获取最大工资的员工
        Optional<Employee> maxEmployee = emps.stream().collect(Collectors.maxBy((x, y) -> Double.compare(x.getSalary(), y.getSalary())));
        System.out.println(maxEmployee.get());
        //获取最小工资值
        Optional<Double> minSalary = emps.stream().map(Employee::getSalary).collect(Collectors.minBy(Double::compare));
        System.out.println(minSalary.get());

    }
@Test
   public void test3_1() {//组函数
       DoubleSummaryStatistics collect = emps.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
       System.out.println(collect.getAverage());//平均值
       System.out.println(collect.getSum());//员工工资总数
       System.out.println(collect.getCount());//员工数
       System.out.println(collect.getMax());//最大工资数
       System.out.println(collect.getMin());//最小工资数
   }
@Test
    public void test4() {
        //收集--分组
        Map<String, List<Employee>> collect = emps.stream().collect(Collectors.groupingBy(Employee::getName));
        // map没有foreach
        //System.out.println(collect);

        //收集--多级分组
        Map<String, Map<Integer, List<Employee>>> collect1 = emps.stream().collect(Collectors.groupingBy(Employee::getName, Collectors.groupingBy(Employee::getAge)));
        System.out.println(collect1);
        Map<String, Map<String, List<Employee>>> collect2 = emps.stream().collect(Collectors.groupingBy(Employee::getName, Collectors.groupingBy((x) -> {
            if (x.getAge() < 18) {
                return "少年";
            } else {
                return "成年";
            }
        })));
        System.out.println(collect2);
    }

 @Test
    public void test5() {
        //收集--分区
        Map<Boolean, List<Employee>> collect = emps.stream().collect(Collectors.partitioningBy((e) -> e.getSalary() > 120.0));
        //满足工资大于120的分一个区,其他的分在另一区
        System.out.println(collect);
    }
@Test
    public void test6(){
        String collect = emps.stream().map(Employee::getName)
                // .distinct()//去重
                // .collect(Collectors.joining());
                //.collect(Collectors.joining("->"));//加上符号  输出   李四->张三->王五->赵六->赵六->田七
                .collect(Collectors.joining("->","(",")"));//加上首尾 输出 (李四->张三->王五->赵六->赵六->田七)
        System.out.println(collect);
    }
上一篇下一篇

猜你喜欢

热点阅读