zoukankan      html  css  js  c++  java
  • jdk1.8新特性总结

    一、Lambda表达式

    什么是Lambda表达式

    Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。

    lambda表达式本质上是一段匿名内部类,也可以是一段可以传递的代码。

    为什么要用?

    lambda是一个匿名函数,我们可以把lambda理解为一个可以传递的代码(将代码像数据一样传递),可以写出更简洁更灵活的代码,增强了代码的可读性。

    lambda 的结构

    a)       一个 Lambda 表达式可以有零个或多个参数

    b)       参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)与(a)效果相同

    c)        所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)

    d)       空圆括号代表参数集为空。例如:() -> 42

    e)       当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a

    f)         Lambda 表达式的主体可包含零条或多条语句

    g)       如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致

    h)       如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

    方法引用

    若lambda体中的内容有方法已经实现了,那么可以使用“方法引用” ,也可以理解为方法引用是lambda表达式的另外一种表现形式并且其语法比lambda表达式更加简单

    (a) 方法引用

    三种表现形式:

    1. 对象::实例方法名

    例如:Consumer<Integer> con = System.out::println;

    1. 类::静态方法名

    例如:BiFunction<Integer, Integer, Integer> biFun = Integer::compare;

    1. 类::实例方法名 (lambda参数列表中第一个参数是实例方法的调用者,第二个参数是实例方法的参数时可用)

    例如:BiFunction<String, String, Boolean> fun = String::equals;

    (b)构造器引用

    格式:ClassName::new

    例如:Function<Integer, Employee> fun = Employee::new;

    (c)数组引用

    格式:Type[]::new

    例如:Function<Integer, String[]> fun = String[]::new;

    lambda使用举例:

     1     /**
     2      * 1.ArrayList的使用
     3      */
     4     @Test
     5     public  void test1(){
     6         //传统方式
     7         Integer[] numArr= {1,6,3,2,4,5,7};
     8         List<Integer> list = Arrays.asList(numArr);
     9         for (Integer num:numArr){
    10             System.out.println("===>"+num);
    11         }
    12 
    13         //lambda方式
    14         list.forEach((num)->{System.out.println("===>"+num); });
    15         System.out.println("-----------------------");
    16 
    17     }
    18 
    19     /**
    20      * 2.Runnable(线程)的使用
    21      */
    22     @Test
    23     public void test2(){
    24         //使用匿名内部类
    25         new Runnable(){
    26             @Override
    27             public void run() {
    28                 System.out.println("hello word!");
    29             }
    30         }.run();
    31         //使用lambda表达式
    32         Runnable runnable = ()-> System.out.println("hello word!");
    33         System.out.println("-----------------------");
    34     }
    35 
    36     /**
    37      * 3.Thread(线程的使用)
    38      */
    39     @Test
    40     public void test3(){
    41         //使用匿名内部类
    42         new Thread(new Runnable(){
    43             @Override
    44             public void run() {
    45                 System.out.println("hello word!");
    46             }
    47         }).start();
    48         //使用lambda表达式
    49         new Thread(()-> System.out.println("hello word"));
    50         System.out.println("-----------------------");
    51     }
    52     /**
    53      * 4.sort排序
    54      */
    55     @Test
    56     public void test4(){
    57         //正常情况使用排序
    58         String[] player = {"aa","cc","bb","ee","dd","gg","ff"};
    59         Arrays.sort(player, new Comparator<String>() {
    60             @Override
    61             public int compare(String o1, String o2) {
    62                 return o1.compareTo(o2);
    63             }
    64             public String compare1(String o1, String o2) {
    65                 return o1;
    66             }
    67         });
    68         Arrays.asList(player).forEach(e-> System.out.println("==>"+e));
    69 
    70         //lambda表达式
    71         //方式1
    72         Comparator<String> comparator = (o1,o2)-> (
    73             o1.compareTo(o2)
    74 
    75         );
    76         Arrays.sort(player,comparator);
    77         Arrays.asList(player).forEach(e-> System.out.println("==>"+e));
    78         //方式2
    79         Arrays.sort(player,(String o1,String o2)->(o1.compareTo(o2)));
    80         Arrays.asList(player).forEach(e-> System.out.println("==>"+e));
    81     }

    二、Stream流

    定义:

    流是Java API的新成员,它允许我们以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。就现在来说,我们可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,也就是说我们不用写多线程代码了。

      Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

      Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream 的并行操作依赖于 Java7 中引入的 Fork/Join 框架(JSR166y)来拆分任务和加速处理过程。

      对stream的操作可以分为两类,中间操作(intermediate operations)和结束操作(terminal operations):

    中间操作总是会惰式执行,调用中间操作只会生成一个标记了该操作的新stream。

          结束操作会触发实际计算,计算发生时会把所有中间操作积攒的操作以pipeline的方式执行,这样可以减少迭代次数。计算完成之后stream就会失效。

    // 1. Individual values

    Stream stream = Stream.of("a", "b", "c");

    // 2. Arrays

    String [] strArray = new String[] {"a", "b", "c"};

    stream = Stream.of(strArray);

    stream = Arrays.stream(strArray);

    // 3. Collections

    List<String> list = Arrays.asList(strArray);

    stream = list.stream();

     

    Stream操作的三个步骤

    创建stream:一个数据源(如:集合、数组),获取一个流

    中间操作(过滤、map):一个中间操作链,对数据源的数据进行处理

    终止操作:一个终止操作,执行中间操作链,并产生结果

    stream的创建:

        // 1,校验通过Collection 系列集合提供的stream()或者paralleStream()

        List<String> list = new ArrayList<>();

        Strean<String> stream1 = list.stream();

     

        // 2.通过Arrays的静态方法stream()获取数组流

        String[] str = new String[10];

        Stream<String> stream2 = Arrays.stream(str);

     

        // 3.通过Stream类中的静态方法of

        Stream<String> stream3 = Stream.of("aa","bb","cc");

     

    Stream的中间操作:

    多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理!而在终止操作时一次性全部处理,称为“惰性求值”。

     

     

    Stream的终止操作:

    终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。

     

     

     

     

     stream使用测试

      1 /**
      2      * Stream操作
      3      */
      4     @Test
      5     public void test5(){
      6         /**
      7          * Stream创建
      8          */
      9         String[] arr = {"1","3","2","4"};
     10         //通过Stream类中的静态方法of
     11         Stream stream1 = Stream.of("1","3","2","4");
     12         //通过Arrays的静态方法stream()获取数组流
     13         Stream stream2 = Arrays.stream(arr);
     14         //通过Collection 系列集合提供的stream()
     15         Stream stream3 = Arrays.asList(arr).stream();
     19     }
     22 
     23     @Test  public void testForEach(){
     24         List<User> list = Arrays.asList(
     25                 new User("张三", 11),
     26                 new User("王九", 20),
     27                 new User("王五", 91),
     28                 new User("张三", 8),
     29                 new User("李四", 44),
     30                 new User("陆二狗", 43),
     31                 new User("刘大麻子", 49)  );
     32         /**
     33          *  forEach 迭代输出每条数据.
     34          */
     35         // java 8 前
     36         System.out.println("java 8 前");
     37         for(User user: list){
     38             System.out.println(user);
     39         }
     40         // java 8 lambda
     41         System.out.println("java 8 lambda");
     42         list.forEach(user -> System.out.println(user));
     43         // java 8 stream lambda
     44          System.out.println("java 8 stream lambda");
     45          list.stream().forEach(user -> System.out.println(user));
     46         System.out.println("-------------------");
     47          //筛选过滤去重
     48         list.stream().filter(e->e.getAge()>11).limit(3).forEach(user -> System.out.println(user));
     49     }
     50     /**   * sort 排序.   */
     51     @Test  public void testSort() {
     52         List<User> list = Arrays.asList(
     53                 new User("张三", 11),
     54                 new User("王九", 20),
     55                 new User("王五", 91),
     56                 new User("张三", 8),
     57                 new User("李四", 44),
     58                 new User("陆二狗", 43),
     59                 new User("刘大麻子", 49)  );
     60         System.out.println("-----排序前-----");
     61         list.forEach(user -> System.out.println(user));
     62         System.out.println("-----排序后-----");
     63         // java 8 前
     64         System.out.println("java 8 前");
     65        Collections.sort(list, new Comparator<User>() {
     66             @Override
     67             public int compare(User o1, User o2) {
     68                 return String.valueOf(o1.getAge()).compareTo(String.valueOf(o2.getAge()));
     69             }
     70        });
     71        for (User user : list) {
     72            System.out.println(user);
     73        }
     74         //java 8 stream 方法引用
     75         System.out.println("java 8 stream 方法引用");
     76         list.stream().sorted(Comparator.comparing(user -> user.getAge())).
     77         forEach(user -> System.out.println(user));
     78        }
     79 
     80     /**   * filter 过滤.   */
     81     @Test  public void testFilter() {
     82         List<User> list = Arrays.asList(
     83                 new User("张三", 11),
     84                 new User("王九", 20),
     85                 new User("王五", 91),
     86                 new User("张三", 8),
     87                 new User("李四", 44),
     88                 new User("陆二狗", 43),
     89                 new User("刘大麻子", 49)  );
     90         System.out.println("-----排序前-----");
     91         // 输出年龄大于50的人
     92          System.out.println("-----过滤前-----");
     93          list.forEach(user -> System.out.println(user));
     94          System.out.println("-----过滤后-----");
     95          //java 8 前
     96          System.out.println("java 8 前");
     97          for(User user: list){
     98             if (user.getAge() > 50) {
     99                 System.out.println(user);
    100             }
    101          }
    102          //java 8 stream
    103          System.out.println("java 8 stream");
    104          list.stream().filter((User user) -> user.getAge() > 50).
    105          forEach(user -> System.out.println(user));
    106     }
    107     /**   * map 映射.   */
    108     @Test  public void testMap() {
    109         List<User> list = Arrays.asList(
    110                 new User("张三", 11),
    111                 new User("王九", 20),
    112                 new User("王五", 91),
    113                 new User("张三", 8),
    114                 new User("李四", 44),
    115                 new User("陆二狗", 43),
    116                 new User("刘大麻子", 49)  );
    117         // 只输出所有人的年龄
    118         list.stream().forEach(user -> System.out.println(user));
    119         System.out.println("映射后------>");
    120 
    121         List<Integer> ages = list.stream().map(user -> user.getAge()).collect(Collectors.toList());
    122         ages.forEach(age -> System.out.println(age));
    123         // 小写转大写
    124          List<String> words = Arrays.asList("aaa", "vvvv", "cccc");
    125          System.out.println("全部大写---->");
    126          List<String> collect = words.stream().map(s -> s.toUpperCase()).collect(Collectors.toList());
    127         collect.forEach(s -> System.out.println(s));
    128     }

    三、新的日期API

    1.8之前JDK自带的日期处理类非常不方便,我们处理的时候经常是使用的第三方工具包,比如commons-lang包等。不过1.8出现之后这个改观了很多,比如日期时间的创建、比较、调整、格式化、时间间隔等。这些类都在java.time包下。比原来实用了很多。

    新的日期API好处:

    * 之前使用的java.util.Date月份从0开始,我们一般会+1使用,很不方便,java.time.LocalDate月份和星期都改成了enum

     * java.util.Date和SimpleDateFormat都不是线程安全的,而LocalDate和LocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改。

     * java.util.Date是一个“万能接口”,它包含日期、时间,还有毫秒数,更加明确需求取舍

     * 新接口更好用的原因是考虑到了日期时间的操作,经常发生往前推或往后推几天的情况。用java.util.Date配合Calendar要写好多代码,而且一般的开发人员还不一定能写对

    LocalDate/LocalTime/LocalDateTime

      LocalDate为日期处理类、LocalTime为时间处理类、LocalDateTime为日期时间处理类,方法都类似,具体可以看API文档或源码,选取几个代表性的方法做下介绍。

    now相关的方法可以获取当前日期或时间,of方法可以创建对应的日期或时间,parse方法可以解析日期或时间,get方法可以获取日期或时间信息,with方法可以设置日期或时间信息,plus或minus方法可以增减日期或时间信息;

    TemporalAdjusters

       这个类在日期调整时非常有用,比如得到当月的第一天、最后一天,当年的第一天、最后一天,下一周或前一周的某天等。

    DateTimeFormatter

    以前日期格式化一般用SimpleDateFormat类,但是不怎么好用,现在1.8引入了DateTimeFormatter类,默认定义了很多常量格式(ISO打头的),在使用的时候一般配合LocalDate/LocalTime/LocalDateTime使用,比如想把当前日期格式化成yyyy-MM-dd hh:mm:ss的形式:

     1 /**
     2      * 时间处理api
     3      */
     4     @Test
     5     public void testDate(){
     6         //当前时间
     7         LocalDate now = LocalDate.now();
     8         System.out.println("当前时间:"+now);
     9 
    10         //前一天时间
    11         LocalDate yesterday = now.minusDays(1);
    12         System.out.println("昨天:"+yesterday);
    13         //上个月
    14         LocalDate lastMonth = now.minusMonths(1);
    15         System.out.println("上个月:"+lastMonth);
    16         //上一周
    17         LocalDate lastWeek = now.minusWeeks(1);
    18         System.out.println("上一周:"+lastWeek);
    19         //一周后
    20         LocalDate nextWeek = now.plusWeeks(1);
    21         System.out.println("一周后:"+nextWeek);
    22         //指定日期
    23         LocalDate ofDate = LocalDate.of(2020, 4, 7);
    24         System.out.println("指定日期:"+ofDate);
    25         //转换日期对象
    26         LocalDate parseDate = LocalDate.parse("2020-04-09");
    27         System.out.println("转换日期对象:"+parseDate);
    28         // 取本月第1天:
    29         LocalDate firstDayOfThisMonth = now.with(TemporalAdjusters.firstDayOfMonth());
    30         LocalDate firstDayOfThisMonth1 = now.withDayOfMonth(1);
    31         System.out.println("本月第一天:"+firstDayOfThisMonth);
    32         System.out.println("本月第一天1:"+firstDayOfThisMonth1);
    33         // 取本月第2天:
    34         LocalDate secondDayOfThisMonth = now.withDayOfMonth(2);
    35         System.out.println("本月第二天:"+secondDayOfThisMonth);
    36         // 取本月最后一天,再也不用计算是28,29,30还是31:
    37         LocalDate lastDayOfThisMonth = now.with(TemporalAdjusters.lastDayOfMonth());
    38         System.out.println("本月最后一天:"+lastDayOfThisMonth);
    39         //获取当前月份,得到结果不用加1
    40         int month = now.getMonthValue();
    41         System.out.println("当前月份:"+month);
    42         int dayOfYear = now.getDayOfYear();
    43         System.out.println("2020年已经度过的天数:"+dayOfYear);
    44         LocalDateTime nowTime = LocalDateTime.now();
    45         String formatDate = DateTimeFormatter.ISO_LOCAL_DATE.format(nowTime);
    46         System.out.println("formatDate:"+formatDate);
    47         DateTimeFormatter formatter =DateTimeFormatter.ofPattern("YYYY-MM-dd HH:mm:ss");
    48         String formatDateTime = formatter.format(nowTime);
    49         System.out.println("formatDateTime:"+formatDateTime);
    50         DateTimeFormatter formatter1 =DateTimeFormatter.ofPattern("YYYY/MM/dd HH:mm:ss");
    51         String formatDateTime1 = formatter1.format(nowTime);
    52         System.out.println("formatDateTime1:"+formatDateTime1);
    53     }

    运行结果:

  • 相关阅读:
    字符串,format格式化及列表的相关进阶操作---day07
    利用wiile双层循环打印各种星星---day06
    双层循环练习,pass_break_continue,和for循环---day06
    类型判断,代码块,流程控制及循环---day05
    频繁项集算法
    Unity 物体移动的理解
    Game1---游戏设计
    精读Hadamard Response论文
    java 创建线程
    Unity游戏开发面试基础知识
  • 原文地址:https://www.cnblogs.com/zhangpeng8888/p/12702169.html
Copyright © 2011-2022 走看看