使用stream()转map去重主键冲突

stream()流可以很方便的我们去做很多操作,比如过滤,转换list,分组等等,这里要讲的是stream的去重.

public class Test {
          
   

    public static void main(String[] args) {
          
   
        List<User> userList = new ArrayList<>();
        User u1 = new User();
        u1.setUserId("11111");
        u1.setUserName("小明");
        u1.setBirthDay(new Date());
        User u2 = new User();
        u2.setUserId("11111");
        u2.setUserName("小红");
        u2.setBirthDay(new Date());
        User u3 = new User();
        u3.setUserId("33333");
        u3.setUserName("小蓝");
        u3.setBirthDay(new Date());
        User u4 = new User();
        u4.setUserId("44444");
        u4.setUserName("小黄");
        u4.setBirthDay(new Date());
        userList.add(u1);
        userList.add(u2);
        userList.add(u3);
        userList.add(u4);
        Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getUserId, Function.identity()));
        System.out.println(JSONUtils.toJSONString(userMap));
    }
}

------------------------------------------------
Exception in thread "main" java.lang.IllegalStateException: Duplicate key User(userId=11111, userName=小明, birthDay=Mon Nov 28 14:56:05 CST 2022)
	at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
	at java.util.HashMap.merge(HashMap.java:1255)
	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.tl.ie.controller.Test.main(Test.java:41)

直接使用map去重时,如果主键重复,就会有 Duplicate key 异常,所以这里当我们主键重复时,需要选择来去重

Map<String, User> userMap = userList.stream().collect(Collectors.toMap(User::getUserId, Function.identity(),(oldData,newData)->newData));
        System.out.println(new ArrayList<>(userMap.values()));

----------------------------------------------------------------------
[User(userId=44444, userName=小黄, birthDay=Mon Nov 28 15:02:23 CST 2022), User(userId=33333, userName=小蓝, birthDay=Mon Nov 28 15:02:23 CST 2022), User(userId=11111, userName=小红, birthDay=Mon Nov 28 15:02:23 CST 2022)]

选择的方法就是 (oldData,newData)->newData ,如果选择oldData就是选择先加入的对象,如果选择newData,就是选择后面的对象覆盖前面的对象,可以看到这里我选择了newData,所以保留的是小红,去掉了小明

经验分享 程序员 微信小程序 职场和发展