Java 使用流API比较两个集合中的对象、查找相等对象和更改对象属性的最佳方法是什么

Java 使用流API比较两个集合中的对象、查找相等对象和更改对象属性的最佳方法是什么,java,java-8,java-stream,Java,Java 8,Java Stream,我有两个对象集合,假设用户: 设置usersFromDb 设置usersPack public class User { private String name; private String email; private boolean isActivated; .. } 我需要比较这两个集合中的对象,如果Set usersFromDb包含与Set usersPack中相同的用户,则必须将Set usersFromDb中这些用户的字段isActivated设置为TRUE 我们可以通过嵌套的f

我有两个对象集合,假设用户:

设置usersFromDb

设置usersPack

public class User {
private String name;
private String email;
private boolean isActivated;
..
}
我需要比较这两个集合中的对象,如果Set usersFromDb包含与Set usersPack中相同的用户,则必须将Set usersFromDb中这些用户的字段isActivated设置为TRUE

我们可以通过嵌套的for each循环来实现:

for(User userD : usersFromDb){
    for(User userP : usersPack){
        if(userDb.equals(userP)){
            userDb.setActivated(true;)
        }
   }
}
我们如何使用流API来实现它? 我试过这样的smth

usersFromDb.stream().filter(d -> d.equals(users.stream().findFirst().get())).peek(d -> d.setActivated(true));
但是没有成功。

假设对象中的equals和hashCode是一致的:

userFromDb.stream().filter(u -> usersPack.contains(u)).forEach(u -> u.setActivated(true));
请注意,首先:

未执行任何操作,因为未使用终端操作(如forEach、close或collect)关闭流。 peek用于检查蒸汽管道内的项目。 应使用Stream::map将对象更改为列表,并使用Stream::collect将对象更改为列表:


usersFromDb.stream.filterusersPack::contains.forEachuser->user.setActivatedtrue;在本例中使用流并没有真正的优势。因为您似乎只对副作用感兴趣,调用setActivated a循环就像这里的流一样清晰和漂亮。但是您可以通过去掉内部循环而调用usersPack.containsuserD来简化代码,就像MarcoLucidi的解决方案一样。这是一种误解,认为peek只用于检查元素。文档中说它的存在主要是为了支持调试。但是,如果你碰巧遇到一个罕见的情况,它是有用的,那么没有理由不使用它。当然,使用peek比滥用map来执行像这样的操作更可取,因为这样的操作不涉及映射,只涉及副作用!该解决方案与使用peek的缺点相同,但也更大、更不清晰。但是,另外,peek也不是一个好的解决方案,最好避免在流管道中产生副作用。使用forEach更清晰,也更不容易出错,就像马可鲁西迪的回答一样。@Lii:我不是只说了。你误解了我的答案。此外,检查与流API上下文中的调试没有什么不同。
List<User> users = usersFromDb.stream()                          // Stream<User>
                              .filter(usersPack::contains)       // if found in usersPack 
                              .map(user -> {                     // map to a User
                                        user.setActivated(true); // ... that is activated
                                        return user; })
                              .collect(Collectors.toList());     // List<User>