从 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()));
- 让您的 IDE 仅根据用户 ID 生成 Users.hashCode() 和 Users.equals()
- 写
cList.removeAll(cList1);
(可能将“Users”重命名为“User”,因为这个 class/object 每个实例只代表一个用户)
问题在于使用 allMatch 要求所有元素都搜索到用户 ID 为真。相反,使用 anyMatch 将给出搜索到的行为。
@JayC667 是正确的,这就是我要采取的行动。现在,如果您不能根据 Users.userId
...
创建 Users.equals
和 Users.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()));
我有一个简单的应用程序,它有 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()));
- 让您的 IDE 仅根据用户 ID 生成 Users.hashCode() 和 Users.equals()
- 写
cList.removeAll(cList1);
(可能将“Users”重命名为“User”,因为这个 class/object 每个实例只代表一个用户)
问题在于使用 allMatch 要求所有元素都搜索到用户 ID 为真。相反,使用 anyMatch 将给出搜索到的行为。
@JayC667 是正确的,这就是我要采取的行动。现在,如果您不能根据 Users.userId
...
Users.equals
和 Users.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()));