I have two list as shown below
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
Expected answer from the comparision should be 5L as it is not in firstList.
Here is my Test 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;
}
}
How can I find the Long values from secondList that are not in the firstList?
If you want to use streams for this purpose the most efficient approach will look like this:
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());
}
The same result could be achieved by utilizing removeAll() and retainAll() methods from the Collection interface. These methods are optimized for ArrayList and perform in a linear time.
You just have to coerce your list of test objects to a list of Long and make a copy of the second list which gonna be mutated.
To demonstrate how these methods work let's consider the following example with lists of Integer values.
removeAll() will remove all elements contained in the given collection from this collection
retainAll() will retain only elements contained in both collections
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);
}
output
result of removeAll: [5, 6, 7, 8, 9]
result of retainAll: [5, 6, 7, 8, 9]