stream流中toMap()api和Duplicate key问题
1、指定key-value,value是对象中的某个属性值。
Map<Integer,String> userMap = userList.stream().collect(Collectors.toMap(User::getId,User::getName));
2、指定key-value,value是对象本身
User->User 是一个返回本身的lambda表达式
Map<Integer,User> userMap = userList.stream().collect(Collectors.toMap(User::getId,User->User));
Function.identity()是简洁写法,也是返回对象本身
Map<Integer,User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));
3、返回其他Map
解决了Key冲突并转为了TreeMap
userList.stream().collect(Collectors.toMap(User::getName, Function.identity(), (oldVal, newVal) -> newVal, TreeMap::new));
4、解决重复key问题
如果生成Map时有重复key(通过key类型的equals方法来判断)就会报错:java.lang.IllegalStateException: Duplicate key。
当发生重复时这里选择第二个key覆盖第一个key的value值,当然如果需要第一个key的value值那就选择oldKey(可提前先进行指定规则的排序)
Map<Integer,User> userMap4 = userList.stream().collect(Collectors.toMap(User::getId, Function.identity(),(oldKey,newKey)->newKey));
PS:当然也可以提前将集合进行去重处理(stream根据指定字段去重)再进行简单的toMap操作。
5、其他示例
- 重复时将前面的value 和后面的value拼接起来
Map<String, String> map = list.stream().collect(Collectors.toMap(Person::getId, Person::getName,(key1 , key2)-> key1+","+key2 ));
//或者将其值相加
Map<String, BigDecimal> map = list.stream().collect(Collectors.toMap(Person::getNo, Person::amount,BigDecimal::add));
- value转为其他DTO实体并解决key重复问题
Map<Integer, ProductCategoryResultDTO> resultDTOMap = byCategoryFidAndEnvironmentTag.stream() .collect(Collectors.toMap(ProductCategory::getCategoryId, v -> { ProductCategoryResultDTO productCategoryResultDTO = new ProductCategoryResultDTO(); productCategoryResultDTO.setStatus(v.getUplowState()); return productCategoryResultDTO; }, (key1, key2) -> key2));
- 代码实战:
public static void main(String[] args) throws JsonProcessingException { UserInfo u1 = new UserInfo(1, "张三"); UserInfo u2 = new UserInfo(2, "李四"); UserInfo u3 = new UserInfo(3, "王五"); UserInfo u4 = new UserInfo(4, "赵六1"); UserInfo u5 = new UserInfo(4, "赵六2"); List<UserInfo> list = Arrays.asList(u1,u2,u3,u4,u5); Map<Integer, String> map = list.stream() .collect(Collectors.toMap(UserInfo::getId, UserInfo::getUserName, (key1, key2) -> key1 + "," + key2)); String mapStr = new ObjectMapper().writeValueAsString(map); System.out.println(mapStr); Set<Object> set = new HashSet<>(); Map<Integer, String> map1 = list.stream() .collect(Collectors.toMap(UserInfo::getId, UserInfo::getUserName, (key1, key2) -> { set.add(key1); return key1; })); System.out.println(new ObjectMapper().writeValueAsString(map1)); System.out.println("set:" + set); }
执行结果: