Java8新特性

    xiaoxiao2022-07-04  173

    一.List的stream()

     

    可以把Stream当成一个高级版本的Iterator。原始版本的Iterator,用户只能一个一个的遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如“过滤掉长度大于10的字符串”、“获取每个字符串的首字母”等,具体这些操作如何应用到每个元素上,就给Stream就好了!

     

    Stream语法详解:http://ifeve.com/stream/

     

    lambda表达式

    lambda:一段带有输入参数的可执行语句块

    lambda表达式的一般语法:

    (Type1 param1, Type2 param2, ..., TypeN paramN) -> {

          statment1;

          statment2;

         //.............

          return statmentM;

        }

     

     

    参数类型省略–绝大多数情况,编译器都可以从上下文环境中推断出lambda表达式的参数类型。这样lambda表达式就变成了:

    (param1,param2, ..., paramN) -> {

      statment1;

      statment2;

      //.............

      return statmentM;

    }

    当lambda表达式的参数个数只有一个,可以省略小括号。lambda表达式简写为:

    param1 -> {

      statment1;

      statment2;

      //.............

      return statmentM;

    }

     

    当lambda表达式只包含一条语句时,可以省略大括号、return和语句结尾的分号。lambda表达式简化为:

    param1 -> statment

     

    lambda表达式语法:http://ifeve.com/lambda/

     

     

     

    二Collectors

    List.stream().collect(Collectors的一系列方法)

     

    Collectors之toMap

    将list转为map

    1.常用方式

    代码如下:

    public Map<Long, String> getIdNameMap(List<Account> accounts) {     return accounts.stream().collect(            Collectors.toMap(Account::getId, Account::getUsername)    );}

     

     

    2.收集成实体本身map

    代码如下:

     

    public Map<Long, Account> getIdAccountMap(List<Account> accounts) {     return accounts.stream().collect(            Collectors.toMap(Account::getId, account -> account)    );}

     

     

    account -> account是一个返回本身的lambda表达式,其实还可以使用Function接口中的一个默认方法代替,使整个方法更简洁优雅:

     

    public Map<Long, Account> getIdAccountMap(List<Account> accounts) {     return accounts.stream().collect(            Collectors.toMap(Account::getId, Function.identity())    );}

     

     

    3.重复key的情况

    代码如下:

    public Map<String, Account> getNameAccountMap(List<Account> accounts) {     return accounts.stream().collect(            Collectors.toMap(Account::getUsername, Function.identity())    );}

     

     

    这个方法可能报错(java.lang.IllegalStateException: Duplicate key),因为name是有可能重复的。toMap有个重载方法,可以传入一个合并的函数来解决key冲突问题:

     

    public Map<String, Account> getNameAccountMap(List<Account> accounts) {     return accounts.stream().collect(            Collectors.toMap(                    Account::getUsername, Function.identity(), (key1, key2) -> key2            )    );}

     

     

    这里只是简单的使用后者覆盖前者来解决key重复问题。

    4.指定具体收集的map

    toMap还有另一个重载方法,可以指定一个Map的具体实现,来收集数据:

     

    public Map<String, Account> getNameAccountMap(List<Account> accounts){     return accounts.stream().collect(            Collectors.toMap(                    Account::getUsername, Function.identity(), (key1, key2) ->                            key2,LinkedHashMap::new)    );}

     

     

    参考:https://zacard.net/2016/03/17/java8-list-to-map/

     

    Collectors之groupingBy

    展示如何使用Java 8 Stream Collectors进行分组,计数,总和和排序List

     

     

    1.分组,计数和排序

     

    1.1分组List并显示其总数。

    Java8Example1.java

     

    package com.mkyong.java8;import java.util.Arrays;import java.util.List;import java.util.Map;import java.util.function.Function;import java.util.stream.Collectors;     public class Java8Example1 {         public static void main(String[] args) {             //3 apple, 2 banana, others 1            List<String> items =                    Arrays.asList("apple", "apple", "banana",                             "apple", "orange", "banana", "papaya");            Map<String, Long> result =                    items.stream().collect(                            Collectors.groupingBy(                                    Function.identity(), Collectors.counting()                            )                    );            System.out.println(result);        }    }

     

     

    Output

     

        {papaya=1, orange=1, banana=2, apple=3}//中文翻译    {番木瓜= 1,橙= 1,香蕉= 2,苹果= 3}

     

     

    1.2添加排序。

    Java8Example2.java

    package com.mkyong.java8;import java.util.Arrays;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import java.util.function.Function;import java.util.stream.Collectors;     public class Java8Example2 {         public static void main(String[] args) {             //3 apple, 2 banana, others 1            List<String> items =                    Arrays.asList("apple", "apple", "banana",                             "apple", "orange", "banana", "papaya");            Map<String, Long> result =                    items.stream().collect(                            Collectors.groupingBy(                                    Function.identity(), Collectors.counting()                            )                    );            Map<String, Long> finalMap = new LinkedHashMap<>();             //Sort a map and add to finalMap            result.entrySet().stream()                    .sorted(Map.Entry.<String, Long>comparingByValue()                            .reversed()).forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));            System.out.println(finalMap);        }    }

     

    Output

     

    {    苹果= 3,香蕉= 2,木瓜= 1,橙= 1}

     

     

     

    2.List Objects

    “分组”用户定义的对象列表的示例。

     

    2.1 Pojo

     

    Item.java

     

    package com.mkyong.java8;import java.math.BigDecimal;     public class Item {         private String name;         private int qty;         private BigDecimal price;         //constructors, getter/setters    }

     

     

     

    2.2 按姓名+数字或数量组合。

    Java8Examples3.java

     

    package com.mkyong.java8;import java.math.BigDecimal;import java.util.Arrays;import java.util.List;import java.util.Map;import java.util.stream.Collectors;     public class Java8Examples3 {         public static void main(String[] args) {             //3 apple, 2 banana, others 1            List<Item> items = Arrays.asList(                     new Item("apple", 10, new BigDecimal("9.99")),                     new Item("banana", 20, new BigDecimal("19.99")),                     new Item("orang", 10, new BigDecimal("29.99")),                     new Item("watermelon", 10, new BigDecimal("29.99")),                     new Item("papaya", 20, new BigDecimal("9.99")),                     new Item("apple", 10, new BigDecimal("9.99")),                     new Item("banana", 10, new BigDecimal("19.99")),                     new Item("apple", 20, new BigDecimal("9.99"))            );            Map<String, Long> counting = items.stream().collect(                    Collectors.groupingBy(Item::getName, Collectors.counting()));            System.out.println(counting);            Map<String, Integer> sum = items.stream().collect(                    Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty)));            System.out.println(sum);        }    }

     

    Output

     

    // Group by + Count    {        番木瓜= 1,香蕉= 2,苹果= 3,猩猩= 1,西瓜= 1     }     // Group by + Sum qty    {        番木瓜= 20,香蕉= 30,苹果= 40,orang = 10,西瓜= 10     }

     

     

    2.3按价格分组

    -Collectors.groupingBy以Collectors.mapping示例为例。

     

    Java8Examples4.java

     

    package com.mkyong.java8;import java.math.BigDecimal;import java.util.Arrays;import java.util.List;import java.util.Map;import java.util.Set;import java.util.stream.Collectors;     public class Java8Examples4 {         public static void main(String[] args) {             //3 apple, 2 banana, others 1            List<Item> items = Arrays.asList(                     new Item("apple", 10, new BigDecimal("9.99")),                     new Item("banana", 20, new BigDecimal("19.99")),                     new Item("orang", 10, new BigDecimal("29.99")),                     new Item("watermelon", 10, new BigDecimal("29.99")),                     new Item("papaya", 20, new BigDecimal("9.99")),                     new Item("apple", 10, new BigDecimal("9.99")),                     new Item("banana", 10, new BigDecimal("19.99")),                     new Item("apple", 20, new BigDecimal("9.99"))            );             //group by price            Map<BigDecimal, List<Item>> groupByPriceMap =                    items.stream().collect(Collectors.groupingBy(Item::getPrice));            System.out.println(groupByPriceMap);             // group by price, uses 'mapping' to convert List<Item> to Set<String>            Map<BigDecimal, Set<String>> result =                    items.stream().collect(                            Collectors.groupingBy(Item::getPrice,                                    Collectors.mapping(Item::getName, Collectors.toSet())                            )                    );            System.out.println(result);        }    }

     

     

     

    Output

        {         19.99 = [        Item {name ='banana',qty = 20,price = 19.99},        Item {name ='banana',qty = 10,price = 19.99}      ]         29.99 = [        Item {name ='orang',qty = 10,price = 29.99},        Item {name ='watermelon',qty = 10,price = 29.99}      ]         9.99 = [        Item {name ='apple',qty = 10,price = 9.99},        Item {name ='papaya',qty = 20,price = 9.99},        Item {name ='apple',qty = 10,price = 9.99},        Item {name ='apple',qty = 20,price = 9.99}      ]    }// group by +映射到Set    {         19.99 = [香蕉]         29.99 = [orang,西瓜],         9.99 = [番木瓜,苹果]    }

     

     

    参考:https://blog.csdn.net/Hatsune_Miku_/article/details/73414406

     

     

     

     

     

     

     

    三.LocalDateTime

    LocalTime :  只包括时间

    LocalDate : 只包括日期

    LocalDateTime : 包括日期和时间

     

    以下测试代码

    简直好用到爆

    public class TimeTest {    @Test   public void testTime() { LocalDateTime time = LocalDateTime.now();   System.out.println(time.toString()); //字符串表示 System.out.println(time.toLocalTime()); //获取时间(LocalTime) System.out.println(time.toLocalDate()); //获取日期(LocalDate) System.out.println(time.getDayOfMonth()); //获取当前时间月份的第几天 System.out.println(time.getDayOfWeek());  //获取当前周的第几天 System.out.println(time.getDayOfYear());  //获取当前时间在该年属于第几天 System.out.println(time.getHour()); System.out.println(time.getMinute()); System.out.println(time.getMonthValue()); System.out.println(time.getMonth()); System.out.println("-----------------------------------");  //格式化输出 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY/MM/dd HH:mm:ss"); System.out.println(time.format(formatter));  //构造时间 LocalDateTime startTime = LocalDateTime.of(2018, 1, 1, 20, 31, 20); LocalDateTime endTime = LocalDateTime.of(2018, 1, 3, 20, 31, 20);  //比较时间 System.out.println(time.isAfter(startTime)); System.out.println(time.isBefore(endTime));    //时间运算,相加相减 System.out.println(time.plusYears(2)); //加2年 System.out.println(time.plusDays(2)); //加两天 System.out.println(time.minusYears(2)); //减两年 System.out.println(time.minusDays(2)); //减两天    //获取毫秒数(使用Instant) System.out.println(time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());//获取秒数(使用Instant) System.out.println(time.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond());    }      }

     

     

    参考:https://www.cnblogs.com/wt20/p/8179118.html

     

     

    最新回复(0)