比较两个列表值并仅从一个列表中查找另一个列表中不存在的值
Comparing two list values and finding only values from one list that do not exist in another
我有两个列表如下所示
List<Test> fisrtList= Arrays.asList(
new Test(1, 1L),
new Test(2, 3L),
new Test(2, 4L)
);
List<Long> secondList=Arrays.asList(3L, 5L);
//Find value of second list that are not in first list
比较的预期答案应该是 5L,因为它不在 firstList 中。
这是我的测试class
public class Test {
public Test(int id, Long idNo) {
this.id=id;
this.idNo=idNo;
}
private int id;
private Long idNo;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Long getIdNo() {
return idNo;
}
public void setIdNo(Long idNo) {
this.idNo = idNo;
}
}
如何从 secondList 中找到 firstList 中没有的 Long 值?
这样就可以了
secondList.removeAll(firstList);
如果你需要secondList
不被修改,你必须先做一个深拷贝,然后使用深拷贝代替secondList
。
如果您想为此目的使用流,最有效的方法如下所示:
public static List<Long> removeIntersection(List<Long> source, List<Test> valuesToRemove) {
Set<Long> toRemove = toSet(valuesToRemove);
return source.stream()
.filter(num -> !toRemove.contains(num))
.collect(Collectors.toList());
}
private static Set<Long> toSet(List<Test> valuesToRemove) {
return valuesToRemove.stream()
.map(Test::getIdNo)
.collect(Collectors.toSet());
}
通过使用 Collection 接口中的 removeAll() 和 retainAll() 方法可以获得相同的结果。这些方法针对 ArrayList 进行了优化,并在线性时间内执行。
你只需要将你的测试对象列表强制转换为 Long 列表,并复制第二个列表的副本,它将被改变。
为了演示这些方法的工作原理,让我们考虑以下包含整数值列表的示例。
removeAll() 将从该集合中删除给定集合中包含的所有元素
retainAll() 将只保留包含在两个集合中的元素
public static void main(String[] args) {
List<Integer> source = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9));
List<Integer> valuesToRemove = new ArrayList<>(List.of(1, 2, 3, 4));
source.removeAll(valuesToRemove);
System.out.println("result of removeAll: " + source);
source = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9));
List<Integer> valuesToRetain = new ArrayList<>(List.of(5, 6, 7, 8, 9));
source.retainAll(valuesToRetain);
System.out.println("result of retainAll: " + source);
}
输出
result of removeAll: [5, 6, 7, 8, 9]
result of retainAll: [5, 6, 7, 8, 9]
我有两个列表如下所示
List<Test> fisrtList= Arrays.asList(
new Test(1, 1L),
new Test(2, 3L),
new Test(2, 4L)
);
List<Long> secondList=Arrays.asList(3L, 5L);
//Find value of second list that are not in first list
比较的预期答案应该是 5L,因为它不在 firstList 中。
这是我的测试class
public class Test {
public Test(int id, Long idNo) {
this.id=id;
this.idNo=idNo;
}
private int id;
private Long idNo;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Long getIdNo() {
return idNo;
}
public void setIdNo(Long idNo) {
this.idNo = idNo;
}
}
如何从 secondList 中找到 firstList 中没有的 Long 值?
这样就可以了
secondList.removeAll(firstList);
如果你需要secondList
不被修改,你必须先做一个深拷贝,然后使用深拷贝代替secondList
。
如果您想为此目的使用流,最有效的方法如下所示:
public static List<Long> removeIntersection(List<Long> source, List<Test> valuesToRemove) {
Set<Long> toRemove = toSet(valuesToRemove);
return source.stream()
.filter(num -> !toRemove.contains(num))
.collect(Collectors.toList());
}
private static Set<Long> toSet(List<Test> valuesToRemove) {
return valuesToRemove.stream()
.map(Test::getIdNo)
.collect(Collectors.toSet());
}
通过使用 Collection 接口中的 removeAll() 和 retainAll() 方法可以获得相同的结果。这些方法针对 ArrayList 进行了优化,并在线性时间内执行。
你只需要将你的测试对象列表强制转换为 Long 列表,并复制第二个列表的副本,它将被改变。
为了演示这些方法的工作原理,让我们考虑以下包含整数值列表的示例。
removeAll() 将从该集合中删除给定集合中包含的所有元素
retainAll() 将只保留包含在两个集合中的元素
public static void main(String[] args) {
List<Integer> source = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9));
List<Integer> valuesToRemove = new ArrayList<>(List.of(1, 2, 3, 4));
source.removeAll(valuesToRemove);
System.out.println("result of removeAll: " + source);
source = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9));
List<Integer> valuesToRetain = new ArrayList<>(List.of(5, 6, 7, 8, 9));
source.retainAll(valuesToRetain);
System.out.println("result of retainAll: " + source);
}
输出
result of removeAll: [5, 6, 7, 8, 9]
result of retainAll: [5, 6, 7, 8, 9]