使用Java8流从另一个不同类型的集合更新集合

使用Java8流从另一个不同类型的集合更新集合,java,collections,java-8,java-stream,Java,Collections,Java 8,Java Stream,这里是Java8。我有两个POJO: public class User { private String id; private String moniker; // ... lots of other fields // Getters & setters down here } public class UserDetail { private String userId; private String moniker; // ... lots of

这里是Java8。我有两个POJO:

public class User {
  private String id;
  private String moniker;
  // ... lots of other fields

  // Getters & setters down here
}

public class UserDetail {
  private String userId;
  private String moniker;
  // ... lots of other fields

  // Getters & setters down here
}
我得到了一个
列表
和一个
集合
。如果该集中有任何
UserDetails
,其
userId
字段与用户列表中的任何
User\id
值匹配,我需要使用
UserDetails
集中的同名字段更新相应的
User\35; moniker

我已经能够以“旧”的方式(Java 8之前的流/集合API)这样做:

final List users=userService.fetch();
最终设置userDetails=userDetailService.fetch();
for(UserDetail UserDetail:userDetails){
for(用户:用户){
if(userDetail.getUserId().equals(user.getId())){
user.setMoniker(userDetail.getMoniker());
}
}
}

我如何使用Java8API做到这一点?也就是说,我如何在这两个集合中循环,对于具有匹配ID的任何元素,使用
UserDetails
中的
moniker
值来更新
Users
中的
moniker
值?

如果将
UserDetails
放在映射中,性能方面会更好

Map<String, String> userDetailsMap = userDetails.stream()
            .collect(Collectors.toMap(UserDetail::getUserId, UserDetail::getMoniker));

users.stream().filter(u -> userDetailsMap.containsKey(u.getId())).forEach(u -> {
        u.setMoniker(userDetailsMap.get(u.getId()));
});
Map userDetailsMap=userDetails.stream()
.collect(Collectors.toMap(UserDetail::getUserId,UserDetail::getMoniker));
users.stream().filter(u->userDetailsMap.containsKey(u.getId()).forEach(u->{
u、 setMoniker(userDetailsMap.get(u.getId());
});

因为您的用户ID依赖于名字对象参数。所以,我已经使用stream和advanceforloop实现了。你可以看一眼。你的问题既棘手又有趣

  • 接近一号

    users.stream().forEach(System.out::println);
    userdetails.stream().forEach(userdetail->{
        for(User user : users) {
            if(user.getId().equals(userdetail.getUserId())){
                user.setMoniker(userdetail.getMoniker());
            }
        }
    });
    System.out.println("********************");
    users.stream().forEach(System.out::println);
    
  • 方法二

    public static List<User> users = getUserList();
    public static void main(String[] args) {
       Set<UserDetail> userdetails = getUserDetails();
       users.stream().forEach(System.out::println);
       //Note: CompareUpdateList is name of my Class
       userdetails.stream().forEach(CompareUpdateList::updateUser);
       System.out.println("********************");
       users.stream().forEach(System.out::println);
    }
    
    public static void updateUser(UserDetail userdetail) {
       for(User user : users) {
           if(user.getId().equals(userdetail.getUserId())){
                user.setMoniker(userdetail.getMoniker());
           }
       }
    }
    
    publicstaticlist-users=getUserList();
    公共静态void main(字符串[]args){
    Set userdetails=getUserDetails();
    users.stream().forEach(System.out::println);
    //注意:CompareUpdateList是我的类的名称
    userdetails.stream().forEach(CompareUpdateList::updateUser);
    System.out.println(“**********************”);
    users.stream().forEach(System.out::println);
    }
    公共静态void updateUser(UserDetail UserDetail){
    for(用户:用户){
    if(user.getId().equals(userdetail.getUserId())){
    user.setMoniker(userdetail.getMoniker());
    }
    }
    }
    
  • 第三种方法

        public static List<User> users = getUserList();
        public static void main(String[] args) {
          Set<UserDetail> userdetails = getUserDetails();
          users.stream().forEach(System.out::println);
          //Note: CompareUpdateList is name of my Class
          userdetails.stream().forEach(CompareUpdateList::updateUser);
          System.out.println("********************");
          users.stream().forEach(System.out::println);
       }
    
    public static void updateUser(UserDetail userdetail) {
       users.stream().forEach(user->{
          if(user.getId().equals(userdetail.getUserId())){
              user.setMoniker(userdetail.getMoniker());
          }
       });
    }
    
    publicstaticlist-users=getUserList();
    公共静态void main(字符串[]args){
    Set userdetails=getUserDetails();
    users.stream().forEach(System.out::println);
    //注意:CompareUpdateList是我的类的名称
    userdetails.stream().forEach(CompareUpdateList::updateUser);
    System.out.println(“**********************”);
    users.stream().forEach(System.out::println);
    }
    公共静态void updateUser(UserDetail UserDetail){
    users.stream().forEach(用户->{
    if(user.getId().equals(userdetail.getUserId())){
    user.setMoniker(userdetail.getMoniker());
    }
    });
    }
    

  • 您有一个
    Set userDetails
    ——我认为
    包含的
    来自
    Set
    ,而不是二次型iteration@Eugene我们不能为并行处理编写每一段代码,这甚至不是OP要求。但是请告诉我会发生什么事Tanks@Adrian(+1)您的解决方案可行,但为了避免我在这里“崇拜货物”,您能解释一下为什么首先将
    userDetails
    放在地图上会更好吗?再次感谢!怎么样
    users.stream().forEach(u->{u.setMoniker(userDetailsMap.getOrDefault(u.getId(),u.getMoniker());})?虽然在流中改变对象是一种不好的做法,但我会说。@Naman使用过滤器时,当调用
    forEach
    时,我们将拥有更少的对象,正如OP所说的“如果该集合中有任何UserDetails…”@hotmeatballsoup嵌套循环是O(n^2),但使用哈希映射时,循环是O(n)
        public static List<User> users = getUserList();
        public static void main(String[] args) {
          Set<UserDetail> userdetails = getUserDetails();
          users.stream().forEach(System.out::println);
          //Note: CompareUpdateList is name of my Class
          userdetails.stream().forEach(CompareUpdateList::updateUser);
          System.out.println("********************");
          users.stream().forEach(System.out::println);
       }
    
    public static void updateUser(UserDetail userdetail) {
       users.stream().forEach(user->{
          if(user.getId().equals(userdetail.getUserId())){
              user.setMoniker(userdetail.getMoniker());
          }
       });
    }