Java 8 Group By一个参数,并获取对象列表作为结果

wwodge7n  于 2023-03-16  发布在  Java
关注(0)|答案(2)|浏览(239)

我有一个用户对象,如下所示:

class User{
   int id;
   String name;
   List<String> subject;
}
class Main {

    public static void main (str args[]) {
    
       List<User> userList = new ArrayList<>();
    
       User user1 = new User(1, "John", Arrays.asList("English"));
       User user2 = new User(2,"Peter", Arrays.asList("English"));
       user user3 = new User(1, "John", Arrays.asList("Chemistry"));
    
       userList.add(user1); userList.add(user2); userList.add(user3);
    }
}

我想按id分组,并获得整个User对象作为响应Map<Integer, List<User>>,如下所示:

User1 = (1, "John", {"English","Chemistry"});
User2 = (2, "Peter", {"English"});

我们如何Map并得到整个对象?

fnvucqvd

fnvucqvd1#

您可以使用toMap收集器并提供mergeFunction。Collectors.toMap()可以使用3个参数调用:第一个用于MapMap的键,在我们的例子中是用户ID,类似于user -> user.getId()或简单地User::getId
第二个参数是Map值,在我们的例子中,我们希望使用用户本身作为值,所以我们只传递user -> user
最后,合并功能将用于具有相同ID(重复)的用户:在本例中,我们希望创建一个具有所有主题的新用户:

private User mergeUsers(User user1, User user2) {
    List<String> allSubjects = new ArrayList<>();
    allSubjects.addAll(user1.getSubject());
    allSubjects.addAll(user2.getSubject());
    return new User(user1.getId(), user1.getName(), allSubjects);
}

现在,让我们按照前面讨论的方式对用户进行流处理和收集:

@Test
void test2() {
    //given
    User user1 = new User(1, "John", Arrays.asList("English"));
    User user2 = new User(2,"Peter", Arrays.asList("English"));
    User user3 = new User(1, "John", Arrays.asList("Chemistry"));
    List<User> users = List.of(user1, user2, user3);

    //when
    Map<Integer, User> usersById = users.stream()
            .collect(Collectors.toMap(u-> u.getId(), u -> u, (u1, u2) -> mergeUsers(u1, u2)));

    //then
    assertThat(usersById.get(1).getSubject())
            .containsExactly("English", "Chemistry");
    assertThat(usersById.get(2).getSubject())
            .containsExactly("English");
}

ps:你可以做一些小的改进,比如使用方法引用或者把这个合并逻辑封装在User类里面:

Map<Integer, User> usersById = users.stream()
            .collect(Collectors.toMap(User::getId, user -> user, User::merge));

阅读更多关于Collectors.toMap和mergingFunction的信息,请访问:https://www.baeldung.com/java-collectors-tomap

von4xj4u

von4xj4u2#

HashMap<Integer, User> users = new HashMap<Integer, User>();
users.put(1,new User(1, "John", Arrays.asList("English")));
users.put(2,new User(2, "Peter", Arrays.asList("English")));
users.put(3,new User(3, "John", Arrays.asList("English")));

这将获取与userId对应的记录,但userId必须唯一。

相关问题