开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
采用java8的stream流,list转成map形式,一般直接使用Collectors类的toMap方法,也可以指定HashMap::new,一起来看看。
1、Collectors.toMap
list.stream().collect(
Collectors.toMap(MileageMonitorDto::getId,MileageMonitorDto::getValue,(k1,k2)->k1));
此方法可能引发空指针异常,确定list不为空,Collectors.toMap方法底层使用了HashMap.merge方法如下:
说明了转map的value不能为null。再查看线上数据是有值为null情况,所以报错。
2、上面方法用HashMap::new替代
list.stream().collect(
HashMap::new,(map,item)->map.put(item.getId(),item.getValue()),HashMap::putAll)
3、收集对象实体本身,Function.identity()返回一个输出跟输入一样的Lambda表达式对象,等价于形如t -> t形式的Lambda表达式
Map<Long, User> maps = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
Function.identity()是一个返回本身的lambda表达式,等价于user->user
转换成map的时候,可能出现重复key的情况,如果不指定一个覆盖规则,上面的代码是会报错:Java.lang.IllegalStateException:Duplicate key。这个时候就需要指定在toMap方法中指定当key冲突时key的选择(这里是选择第二个key覆盖第一个key)。
转成map的时候,最好使用下面的方式:
Map<Long, User> maps = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(), (key1, key2) -> key2));
4、转Map的值不是对象,而是对象的某个属性
Map<Long, String> maps = userList.stream().collect(Collectors.toMap(User::getId, User::getAge, (key1, key2) -> key2));
指定返回一个新的LinkedHashMap:
Map<String, WarningCodeModel> collect = threeLevelWarningList.stream().collect(Collectors.toMap(k -> k.getCode() + k.getCityRegion(), Function.identity(),(key1, key2) -> key1, LinkedHashMap::new));
5、用groupingBy 或者 partitioningBy进行分组
根据一个字段或者属性分组也可以直接用groupingBy方法,List以ID分组 Map<Integer,List>
Map<Integer, List> groupBy = userList.stream().collect(Collectors.groupingBy(Apple::getId));
partitioningBy可以理解为特殊的groupingBy,key值为true和false,当然此时方法中的参数为一个判断语句(用于判断的函数式接口)
Map<Boolean, List> userMap = userList.collect(Collectors.partitioningBy(p -> p.getAge() < 18)); System.out.println("userMap number<18: " + userMap.get(true).size()); System.out.println("userMap number>=18: " + userMap.get(false).size());