美文网首页后端开发
【十】Java8新特性

【十】Java8新特性

作者: 吴里庆庆 | 来源:发表于2018-05-28 22:25 被阅读0次

    一、主要内容

    • 1.Lambda表达式
    • 2.函数式接口
    • 3.方法引用和构造器引用
    • 4.Stream API
    • 5.接口中的默认方法与静态方法
    • 6.新时间日期API
    • 7.其他新特性

    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 四大内置核心函数式接口

    • Java8 内置的四大核心函数式接口
    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 归约与收集

    • 2.6.1 归约
     @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());
        }
    
    • 2.6.2 收集
    
     @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());
    
        }
    
    • 2.6.3 收集-组函数
    @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());//最小工资数
       }
    
    • 2.6.4 收集-分组
    @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);
        }
    
    • 2.6.5 收集-分区
    
     @Test
        public void test5() {
            //收集--分区
            Map<Boolean, List<Employee>> collect = emps.stream().collect(Collectors.partitioningBy((e) -> e.getSalary() > 120.0));
            //满足工资大于120的分一个区,其他的分在另一区
            System.out.println(collect);
        }
    
    • 2.6.6 收集-连接
    @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);
        }
    

    相关文章

      网友评论

        本文标题:【十】Java8新特性

        本文链接:https://www.haomeiwen.com/subject/pbcnjftx.html