从 java 的 Set2 中删除 Set1 中的值

Remove values from Set1 which are there in Set2 in java

我有一个简单的应用程序,它有 2 套。我必须根据 Set2 的值从 Set1 中删除。
这是我写的代码:

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) {
        Set<Users> cList = new HashSet<Users>();

        Users c = new Users();
        c.setUserId("modelId1");
        Set<String> cRoles = new HashSet();
        cRoles.add("USER");
        c.setRoles(cRoles);
        cList.add(c);

        c = new Users();
        c.setUserId("modelId2");
         cRoles = new HashSet();
        cRoles.add("ADMIN");
        c.setRoles(cRoles);
        cList.add(c);
   

        Set<Users> cList1 = new HashSet<Users>();

        c = new Users();
        c.setUserId("modelId1");
        cRoles = new HashSet();
        cRoles.add("ADMIN");
        c.setRoles(cRoles);
        cList1.add(c);  
  
        cList.removeAll(cList1.stream().filter(e -> cList.stream()
                .allMatch(p -> e.getUserId().equals(p.getUserId())))
                .collect(Collectors.toSet()));

        System.out.println(cList.size());


    }
}

用户class如下:

public class Users {
    private String userId;

    private Set<String> roles;


    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }

    public Set<String> getRoles() {
        return  roles;
    }
    public void setRoles(Set<String> roles) {
        this.roles = roles;
    }

}

我的期望是必须删除 cList 中的值,这些值仅基于用户标识存在于 cList1 中。如果 userid 匹配,则无论角色如何,都需要从 cList 中删除整个对象。
我写的逻辑没有按预期工作。任何人都可以提出需要更改的内容,以便它按我的预期工作。非常感谢。

编辑 尝试将 allMatch 更改为 anyMatch ,但仍然无效。

cList.removeAll(cList1.stream().filter(e -> cList.stream()
                .anyMatch(p -> e.getUserId().equals(p.getUserId())))
                .collect(Collectors.toSet()));
  1. 让您的 IDE 仅根据用户 ID 生成 Users.hashCode() 和 Users.equals()
  2. cList.removeAll(cList1);

(可能将“Users”重命名为“User”,因为这个 class/object 每个实例只代表一个用户)

问题在于使用 allMatch 要求所有元素都搜索到用户 ID 为真。相反,使用 anyMatch 将给出搜索到的行为。

@JayC667 是正确的,这就是我要采取的行动。现在,如果您不能根据 Users.userId...

创建 Users.equalsUsers.hashcode

编辑 这种情况下最好的解决办法是使用Collection.removeIf:

Set<String> removeIds = cList1.stream().map(Users::getUserId).collect(Collectors.toSet());
cList.removeIf(u -> removeIds.contains(u.getUserId()));

编辑结束: 我之前的想法

您可以这样做:

Set<String> removeIds = cList1.stream().map(Users::getUserId).collect(Collectors.toSet());
Set<Users> remove = cList.stream().filter(
        u -> removeIds.contains(u.getUserId())
    ).collect(Collectors.toSet());
cList.removeAll(remove);

或所有流版本(性能问题,因为您将多次流式传输 cList1):

cList.removeAll(cList.stream().filter(
    u -> cList1.stream().map(Users::getUserId).anyMatch(id -> id == u.getUserId())
).collect(Collectors.toSet()));