I have two ArrayList
as follows:
original: 12, 16, 17, 19, 101
selected: 16, 19, 107, 108, 109
Here is a function to find intersection of various collections (more than 2) -
public static <T, C extends Collection<T>> C findIntersection(C newCollection,
Collection<T>... collections) {
boolean first = true;
for (Collection<T> collection : collections) {
if (first) {
newCollection.addAll(collection);
first = false;
} else {
newCollection.retainAll(collection);
}
}
return newCollection;
}
Usage -
public static void main(String[] args) {
List<Integer> l1 = List.of(1, 3, 5, 7, 9, 11, 13);
List<Integer> l2 = List.of(1, 2, 3, 5, 8, 13);
List<Integer> l3 = List.of(2, 3, 5, 7, 11, 13);
Set<Integer> intersection = findIntersection(new HashSet<>(), l1, l2, l3);
System.out.println(intersection);
}
Intersection: original.retainAll(selected)
.
After that original will contain only elements present in both collections. Returns true if anything changed.
WARNING: This method is very slow for large collections
Using Guava library:
List<Integer> listA = Lists.newArrayList(12,16,17,19,101);
List<Integer> listB = Lists.newArrayList(16,19,107,108,109);
Set<Integer> intersection = Sets.intersection(Sets.newHashSet(listA), Sets.newHashSet(listB));
listA.removeAll(intersection);
listB.removeAll(intersection);
package LAB8Pack;
import java.util.HashSet;
import java.util.Iterator;
import java.lang.StringBuilder;
public class HashSetDemo {
public static void main(String[] args) {
HashSet<String> round = new HashSet<String> ();
HashSet<String> green = new HashSet<String> ();
// Add elements to 'round' and 'green' sets
//----------------------------------------------------
round.add("peas");
green.add("peas");
round.add("watermelon");
green.add("watermelon");
round.add("basketball");
green.add("chameleon");
round.add("chameleon");
green.add("grass");
round.add("eyes");
green.add("book");
// Create 'setUnion' and 'setInter'
// ---------------------------------------------------
HashSet<String> setUnion = new HashSet<String>();
// Use this to find the intersection
HashSet<String> SETINTER = new HashSet<String>();
HashSet<String> setInter1 = new HashSet<String>(round);
HashSet<String> setInter2 = new HashSet<String>(green);
// Add all the elements to one set
setUnion.addAll(round);
setUnion.addAll(green);
SETINTER.addAll(setUnion);
// Create an intersection
setInter1.removeAll(green); // Get unique items in round
setInter2.removeAll(round); // Get unique items in green
SETINTER.removeAll(setInter2); // Remove items that are unique to green
SETINTER.removeAll(setInter1); // Remove items that are unique to round
//----------------------------------------------------
// DISPLAY RESULTS
// ===================================================
System.out.println("Content of set round");
System.out.println("-----------------------");
System.out.println(OutputSet(round));
System.out.println("Content of set green");
System.out.println("-----------------------");
System.out.println(OutputSet(green));
System.out.println("Content of set Union");
System.out.println("-----------------------");
System.out.println(OutputSet(setUnion));
System.out.println("Content of set Intersection");
System.out.println("-----------------------");
System.out.println(OutputSet(SETINTER));
}
// METHODS
// =======================================================
static StringBuilder OutputSet (HashSet<String> args) {
Iterator iterator = args.iterator();
StringBuilder sB = new StringBuilder ();
while (iterator.hasNext()) {
sB.append(iterator.next() + " \n");
}
return sB;
}
}
Using Java 8+ streams:
List<Integer> result = original.stream()
.distinct()
.filter(selected::contains)
.collect(Collectors.toList());
There is a new library available underscore-java. It can do difference and intersection for lists and arrays. Live example.
Code example:
List<Integer> original = Arrays.asList(12, 16, 17, 19, 101);
List<Integer> selected = Arrays.asList(16, 19, 107, 108, 109);
List<Integer> add = U.difference(selected, U.intersection(original, selected));
List<Integer> remove = U.difference(original, selected);