I was looking similar but I wanted the difference in either list (uncommon elements between the 2 lists).
Let say I have:
List<String> oldKeys = Arrays.asList("key0","key1","key2","key5");
List<String> newKeys = Arrays.asList("key0","key2","key5", "key6");
And I wanted to know which key has been added and which key is removed i.e I wanted to get (key1, key6)
Using org.apache.commons.collections.CollectionUtils
List<String> list = new ArrayList<>(CollectionUtils.disjunction(newKeys, oldKeys));
Result
["key1", "key6"]
First convert list to sets.
// create an empty set
Set<T> set = new HashSet<>();
// Add each element of list into the set
for (T t : list)
set.add(t);
You can use Sets.difference(Set1, Set2)
, which returns extra items present in Set1.
You can use Sets.difference(Set2, Set1)
, which returns extra items present in Set2.
You can use CollectionUtils from Apache Commons Collections 4.0:
new ArrayList<>(CollectionUtils.subtract(a, b))
I was looking for a different problem and came across this, so I will add my solution to a related problem: comparing two Maps.
// make a copy of the data
Map<String,String> a = new HashMap<String,String>(actual);
Map<String,String> e = new HashMap<String,String>(expected);
// check *every* expected value
for(Map.Entry<String, String> val : e.entrySet()){
// check for presence
if(!a.containsKey(val.getKey())){
System.out.println(String.format("Did not find expected value: %s", val.getKey()));
}
// check for equality
else{
if(0 != a.get(val.getKey()).compareTo(val.getValue())){
System.out.println(String.format("Value does not match expected: %s", val.getValue()));
}
// we have found the item, so remove it
// from future consideration. While it
// doesn't affect Java Maps, other types of sets
// may contain duplicates, this will flag those
// duplicates.
a.remove(val.getKey());
}
}
// check to see that we did not receive extra values
for(Map.Entry<String,String> val : a.entrySet()){
System.out.println(String.format("Found unexpected value: %s", val.getKey()));
}
It works on the same principle as the other solutions but also compares not only that values are present, but that they contain the same value. Mostly I've used this in accounting software when comparing data from two sources (Employee and Manager entered values match; Customer and Corporate transactions match; ... etc)
List<String> l1 = new ArrayList<String>();
l1.add("apple");
l1.add("orange");
l1.add("banana");
l1.add("strawberry");
List<String> l2 = new ArrayList<String>();
l2.add("apple");
l2.add("orange");
System.out.println(l1);
System.out.println(l2);
for (String A: l2) {
if (l1.contains(A))
l1.remove(A);
}
System.out.println("output");
System.out.println(l1);
Output:
[apple, orange, banana, strawberry]
[apple, orange]
output
[banana, strawberry]
You may call U.difference(lists)
method in underscore-java library. I am the maintainer of the project. Live example
import com.github.underscore.U;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(1, 2);
List<Integer> list3 = U.difference(list1, list2);
System.out.println(list3);
// [3]
}
}
With Stream API you can do something like this:
List<String> aWithoutB = a.stream()
.filter(element -> !b.contains(element))
.collect(Collectors.toList());
List<String> bWithoutA = b.stream()
.filter(element -> !a.contains(element))
.collect(Collectors.toList());
You can use filter
in the Java 8 Stream
library
List<String> aList = List.of("l","e","t","'","s");
List<String> bList = List.of("g","o","e","s","t");
List<String> difference = aList.stream()
.filter(aObject -> {
return ! bList.contains(aObject);
})
.collect(Collectors.toList());
//more reduced: no curly braces, no return
List<String> difference2 = aList.stream()
.filter(aObject -> ! bList.contains(aObject))
.collect(Collectors.toList());
Result of System.out.println(difference);
:
[e, t, s]
If you only want find missing values in b, you can do:
List toReturn = new ArrayList(a);
toReturn.removeAll(b);
return toReturn;
If you want to find out values which are present in either list you can execute upper code twice. With changed lists.
Here is a generic solution for this problem.
public <T> List<T> difference(List<T> first, List<T> second) {
List<T> toReturn = new ArrayList<>(first);
toReturn.removeAll(second);
return toReturn;
}
Source: Stackoverflow.com