使用stream流对list中某个字段分组映射成map,如果key重复会报错
public class MapTest {
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
User u1 = new User();
u1.setName("张三");
u1.setAge(20);
u1.setMoney(3000);
User u2 = new User();
u2.setName("李四");
u2.setAge(30);
u2.setMoney(6000);
User u3 = new User();
u3.setName("张三");
u3.setAge(20);
u3.setMoney(4000);
userList.add(u1);
userList.add(u2);
userList.add(u3);
Map<String, User> nameToUserMap = userList.stream().collect(Collectors.toMap(User::getName, e -> e));
System.out.println(JSONObject.toJSONString(nameToUserMap));
}
}
报错信息
Exception in thread "main" java.lang.IllegalStateException: Duplicate key com.hyx.chatgpt.example.demo.User@a090242c
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
at java.util.HashMap.merge(HashMap.java:1254)
at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at com.hyx.chatgpt.example.demo.MapTest.main(MapTest.java:41)
对于key相同的请求,要添加响应的处理策略
解决办法:
public class MapTest {
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
User u1 = new User();
u1.setName("张三");
u1.setAge(20);
u1.setMoney(3000);
User u2 = new User();
u2.setName("李四");
u2.setAge(30);
u2.setMoney(6000);
User u3 = new User();
u3.setName("张三");
u3.setAge(20);
u3.setMoney(4000);
userList.add(u1);
userList.add(u2);
userList.add(u3);
Map<String, User> nameToUserMap = userList.stream().collect(Collectors.toMap(User::getName, e -> e,(e, f) -> e));
System.out.println(JSONObject.toJSONString(nameToUserMap));
}
}
Map<String, User> nameToUserMap = userList.stream().collect(Collectors.toMap(User::getName, e -> e,(e, f) -> e));
Collectors.toMap:
第一个参数(User::getName 表示选择User的getName作为map的key值;
第二个参数e -> e表示选择将原来的对象作为map的value值;
第三个参数(e, f) -> e ,如果e与f的key值相同,选择e作为那个key所对应的value值。
list转成map时 map的value值是list对象中某个属性拼接成的字符串:
对于需要拼接的字段需要先过滤空值 以免报错
public class MapTest {
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
User u1 = new User();
u1.setName("张三");
u1.setAge(20);
u1.setMoney(3000);
User u2 = new User();
u2.setName("李四");
u2.setAge(30);
u2.setMoney(6000);
User u3 = new User();
u3.setName("张三");
u3.setAge(20);
u3.setMoney(4000);
User u4 = new User();
// u4.setName("王五");
u4.setAge(20);
u4.setMoney(4000);
userList.add(u1);
userList.add(u2);
userList.add(u3);
userList.add(u4);
Map<Integer, String> ageMap = userList.stream().
filter(item -> StringUtils.isNotEmpty(item.getName()))
.collect(Collectors.toMap(User::getAge, e -> e.getName(), (e, f) -> e + "," + f));
System.out.println(JSONObject.toJSONString(ageMap));
}
}
运行结果:{20:"张三,张三",30:"李四"}