zoukankan      html  css  js  c++  java
  • Java 8 有哪些新特性

    一、支持 lambda 表达式

    例如:查询学生信息,并打印

     List<Student> studentList = Student.findAllStudent();
            for(Student student:studentList){
                System.out.println(student);
            }

     使用 Lambda 的写法

     Student.findAllStudent().stream().forEach(e->System.out.println(e));
     Student.findAllStudent().forEach(e->System.out.println(e));

     例如:创建一个线程

      Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+":重写run 方法");
                }
            };
    
            Thread t1 = new Thread(runnable,"t1");
            t1.start();

     使用 Lambda 的写法:

    new Thread(()->System.out.println(Thread.currentThread().getName()+":重写run 方法"),"t2").start();

     使用 Lambda 的前提:必须满足是函数式接口,Runnable 就是一个函数式接口,用@FunctionalInterface 申明

     此外: Java8 提供了模板函数式的接口在包: Java.util.function 

    01. 消费者接口

       

     02.函数接口

       

      03.判断接口

      

     04.提供者接口

        

     除了上述接口,Java 就有的函数式接口Runnabkle Callable Comparator

     

     

     Lambda中使用的变量必须显示的声明为 final

    方法引用:

    Student.findAllStudent().stream().forEach(System.out::println);

     例如:

    (Student s)->s.getSex(); 

    Student::getSex

    例如:输出所有学生的姓名

    Student.findAllStudent().stream().map(Student::getName).forEach(System.out::println);

      复合函数:

    Function<Integer,Integer> f = x->x+4;
            Function<Integer,Integer> g = x->x*2;
            Function<Integer,Integer> k = f.andThen(g);
            System.out.println(k.apply(2));

    解析:先将输入 +4 ,将得到的结果 *2 ,组合使用函数

    二、引入流

    流在 java.util.stream.Stream,支持数据处理操作的源生成的元素序列。

    filter :接收Lambda,从流中排除某些元素

    map: 接受一个lambda,将元素转换成其他形式或者提取信息

    limit: 截断流,使元素不超过指定数量

    collect: 将流转换为其他形式

     例如:查询并打印年龄大于20的学生信息

     List<Student> students = Student.findAllStudent();
            List<Student> res = new ArrayList<>();
            for(Student student :students){
                if(student.getAge()>20){
                    res.add(student);
                }
            }
            for(Student student: res){
                System.out.println(student);
            }

     使用流:

      Student.findAllStudent().stream()
                  .filter(e->e.getAge()>20)
                  .forEach(System.out::println);

     例如:查询所有北京的学生,并按年龄升序输出

      Student.findAllStudent().stream()
                    .filter(e->e.getAddress().equals("北京"))
                    .sorted(Comparator.comparing(Student::getAge))
                    .forEach(System.out::println);

    内部迭代与外部迭代:

    for-each 结构是一个语法糖,背后的是 Iterator 还丑陋的东西。

    流可以分为:中间操作、终端操作

    中间操作: filter 、 sorted 等会返回另一个流。{filter、map、limit、sorted、distinct}

    终端操作:终端操作会从流的流水线生成结果,结果不是流的值。 void 、list 等结果.{forEach、count、collect}

     例如:查询集合中的偶数,去重复

     List<Integer> numbers = Arrays.asList(10,12,2,12,10,1,2);
    
          numbers.stream()
                  .filter(e->e%2==0)
                  .distinct()
                  .forEach(System.out::println);

    例如:查询集合中前 3 个数据

    numbers.stream()
                  .limit(3)
                  .forEach(System.out::println);

    例如:忽略集合中前3个数据

    numbers.stream()
                  .skip(3)
                  .forEach(System.out::println);

    例如:查询学生信息中地址,去重

     Student.findAllStudent().stream()
                 .map(e->e.getAddress())
                 .distinct()
                 .forEach(System.out::println);

     例如:将【“Hello”,“World”】 处理为:【“H”,"e","l","o"...】

     List<String> str = Arrays.asList("Hello","World");
         List<String[]> res = str.stream()
                 .map(e->e.split(""))
                 .distinct()
                 .collect(toList());

    返回的是2个String 数组,而想要的结果是一个string 数组

     List<String> res = str.stream()
               .map(e->e.split(""))
               .flatMap(Arrays::stream)
               .distinct()
               .collect(toList());
       System.out.println(res);

    flatMap : 把流中的每个值都换成另一个流,然后把所有的流连接起来形成一个流。

    例如:判断学生中是否所有的年龄都小于20

       boolean res =Student.findAllStudent().stream()
               .allMatch(e->e.getAge()<20);
       System.out.println(res);

    例如:判断学生中是否有成都的

     boolean res =Student.findAllStudent().stream()
               .anyMatch(e->e.getAddress()=="成都");
       System.out.println(res);

    规约:求学生的年龄和

    int sum = Student.findAllStudent().stream()
                    .map(Student::getAge)
                    .reduce(0,(e1,e2)->e1+e2);
            System.out.println(sum);
     int sum = Student.findAllStudent().stream()
                    .map(Student::getAge)
                    .reduce(0,Integer::sum);
            System.out.println(sum);

    无初始值-规约:

      Optional<Integer> sum = Student.findAllStudent().stream()
                    .map(Student::getAge)
                    .reduce((e1,e2)->e1+e2);
            System.out.println(sum);

    例如:返回所有学生姓名字符串,按字母顺序排列

     String str = Student.findAllStudent().stream()
                   .map(Student::getName)
                   .distinct()
                   .sorted()
                   .reduce("",(e1,e2)->e1+e2);
           System.out.println(str);

    例如:查找年龄最小的学习年龄

     Optional<Integer> min = Student.findAllStudent().stream()
                    .map(Student::getAge)
                    .reduce(Integer::min);
            System.out.println(min);

    使用 groupingBy 按城市分组查询:

    Map<String,List<Student>> map = Student.findAllStudent().stream()
                    .collect(groupingBy(Student::getAddress));
    
    
            for(Map.Entry<String,List<Student>> entry: map.entrySet()){
                System.out.println(entry.getKey()+","+entry.getValue());
            }

     收集器的 Joining 汇总

    joining 会把流中每一个对象应用 toString 方法得到的字符串连接成一个字符串。

    例如:将城市去重以字符串返回

      String str = Student.findAllStudent().stream()
                 .map(Student::getAddress)
                 .distinct()
                 .collect(joining());
         System.out.println(str);

     String str = Student.findAllStudent().stream()
                 .map(Student::getAddress)
                 .distinct()
                 .collect(joining(","));
         System.out.println(str);

     例如:将学生按年龄分组

     Map<Integer,List<Student>> map = Student.findAllStudent().stream()
                    .collect(groupingBy(Student::getAge));
    
            for(Map.Entry<Integer,List<Student>> entry:map.entrySet()){
                System.out.println(entry.getKey()+","+entry.getValue());
            }

     使用 counting 

    计算每个年龄组人的个数

    Map<Integer,Long> map = Student.findAllStudent().stream()
                    .collect(groupingBy(Student::getAge,counting()));
    
            for(Map.Entry<Integer,Long> entry:map.entrySet()){
                System.out.println(entry.getKey()+","+entry.getValue());
            }

    并行流

    使用 parallelStream 方法把集合转换为并行流

    打印学生信息

     Student.findAllStudent().parallelStream().forEach(System.out::println);

    输出学生姓名

     String str = Student.findAllStudent().parallelStream()
                   .map(Student::getName)
                   .collect(joining(","));
           System.out.println(str);

    分支/合并框架(ForkJoinPool)

    目的:以递归方式将可以并行的任务拆分成更小的任务,然后将每个子任务的结果合并起来生成整体的结果

    继承 RecursiveTask<T>

    Spliterator : 可分迭代器,可并行遍历数据源中的数据

    三、默认方法

    问题:接口中的方法,子类必须实现。由于 java8 接口增加许多,为了不带来更多的问题,添加新的机制

    1.java8 允许在接口内声明静态方法

    2.java8 引入一个新的功能 ,默认方法。接口能够提供具体的实现

    四、Optional 取代 null

    java.util.Optional<T>  

    当变量存在时,Optional 对对象简单的封装,当变量不存在时,缺失的值被建模成 kong  的optional 对象。由 Optional.empty() 返回

    五、CompleteableFuture 组合式异步编程

    Future 接口,java5引入。提供了异步操作。

    六、新的日期与时间 API

    java.util.Date 、 java.utlo.Calender 设计的缺陷

    缺陷: java.util.Date  无法表示日期,只能以毫秒精确时间。年份的起始选择的是 1900 年,月份从 0 开始。

    缺陷:java.util.Calendar 月份呢依然是从 0开始,取消 1900 年开始。

    新的时间: java.time 包

    1.获取当前日期

     LocalDate today = LocalDate.now();
     System.out.println(today);

     2.获取指定日期

     LocalDate localDate = LocalDate.of(2018,4,5);
    
            System.out.println(localDate.getDayOfWeek());
    
            System.out.println(localDate.getDayOfMonth());
    
            System.out.println(localDate.getDayOfYear());

     3.指定时间

    LocalTime localTime = LocalTime.of(13,14,50);
    
            System.out.println(localTime.getHour());
    
            System.out.println(localTime.getMinute());
    
            System.out.println(localTime.getSecond());

  • 相关阅读:
    【C#进阶系列】06 类型和成员基础
    纪中5日T1 1564. 旅游
    纪中17日T1 2321. 方程
    纪中17日T2 2322. capacitor
    纪中10日T1 2313. 动态仙人掌
    纪中14日听课小结 图论 最短路 二分图 差分约束
    一个抓猫的游戏 消遣GAME 持续更新中!
    洛谷P1464 Function  HDU P1579 Function Run Fun
    洛谷P1976 鸡蛋饼
    纪中12日T1 2307. 选择
  • 原文地址:https://www.cnblogs.com/baizhuang/p/11195061.html
Copyright © 2011-2022 走看看