Here's a plain implementation without using any third-party library. Main advantage over retainAll, removeAll and addAll is that these methods don't modify the original lists input to the methods.
public class Test {
public static void main(String... args) throws Exception {
List<String> list1 = new ArrayList<String>(Arrays.asList("A", "B", "C"));
List<String> list2 = new ArrayList<String>(Arrays.asList("B", "C", "D", "E", "F"));
System.out.println(new Test().intersection(list1, list2));
System.out.println(new Test().union(list1, list2));
}
public <T> List<T> union(List<T> list1, List<T> list2) {
Set<T> set = new HashSet<T>();
set.addAll(list1);
set.addAll(list2);
return new ArrayList<T>(set);
}
public <T> List<T> intersection(List<T> list1, List<T> list2) {
List<T> list = new ArrayList<T>();
for (T t : list1) {
if(list2.contains(t)) {
list.add(t);
}
}
return list;
}
}
Answer from adarshr on Stack OverflowHere's a plain implementation without using any third-party library. Main advantage over retainAll, removeAll and addAll is that these methods don't modify the original lists input to the methods.
public class Test {
public static void main(String... args) throws Exception {
List<String> list1 = new ArrayList<String>(Arrays.asList("A", "B", "C"));
List<String> list2 = new ArrayList<String>(Arrays.asList("B", "C", "D", "E", "F"));
System.out.println(new Test().intersection(list1, list2));
System.out.println(new Test().union(list1, list2));
}
public <T> List<T> union(List<T> list1, List<T> list2) {
Set<T> set = new HashSet<T>();
set.addAll(list1);
set.addAll(list2);
return new ArrayList<T>(set);
}
public <T> List<T> intersection(List<T> list1, List<T> list2) {
List<T> list = new ArrayList<T>();
for (T t : list1) {
if(list2.contains(t)) {
list.add(t);
}
}
return list;
}
}
Collection (so ArrayList also) have:
col.retainAll(otherCol) // for intersection
col.addAll(otherCol) // for union
Use a List implementation if you accept repetitions, a Set implementation if you don't:
Collection<String> col1 = new ArrayList<String>(); // {a, b, c}
// Collection<String> col1 = new TreeSet<String>();
col1.add("a");
col1.add("b");
col1.add("c");
Collection<String> col2 = new ArrayList<String>(); // {b, c, d, e}
// Collection<String> col2 = new TreeSet<String>();
col2.add("b");
col2.add("c");
col2.add("d");
col2.add("e");
col1.addAll(col2);
System.out.println(col1);
//output for ArrayList: [a, b, c, b, c, d, e]
//output for TreeSet: [a, b, c, d, e]
java - Find intersection between two ArrayLists - Stack Overflow
Intersection between two arraylist Java - Stack Overflow
java - Find the intersection of ArrayList elements inside an ArrayList - Code Review Stack Exchange
Intersection of Two Dimensional ArrayList in Java - Stack Overflow
You could make it easier to understand by writing it like this:
/**
* Computes the intersection of two Lists of Strings, returning it as a new ArrayList of Strings
*
* @param list1 one of the Lists from which to compute an intersection
* @param list2 one of the Lists from which to compute an intersection
*
* @return a new ArrayList of Strings containing the intersection of list1 and list2
*/
public ArrayList<String> intersection( List<String> list1, List<String> list2) {
ArrayList<String> result = new ArrayList<String>(list1);
result.retainAll(list2);
return result;
}
Java collections already have support for this with the retainAll call. Rather than return a new set, the intersection happens in place, which is why you must create a new ArrayList if you want to retain the original list1. retainAll returns a boolean if the calling object is modified
ArrayList<String> list1 = new ArrayList<String>();
list1.add("A");
list1.add("B");
list1.add("C");
ArrayList<String> list2 = new ArrayList<String>();
list2.add("D");
list2.add("B");
list2.add("C");
ArrayList<String> intersection = new ArrayList<String>(list1);
intersection.retainAll(list2);
for(String s: intersection){
System.out.println(s);
}
Output:
B
C
The intersection of two lists is done using the retainAll() method.
It update the list, so if you don't want that, you should copy the list first.
If you have more than 2 lists, you copy the first and then call retainAll() for each of the remaining lists.
ArrayList<ArrayList<String>> lists = ...
List<String> intersection = new ArrayList<>(lists.get(0));
for (List<String> list : lists.subList(1, lists.size()))
intersection.retainAll(list);
However performance will be a bad O(n*m), where n and m are the sizes of the two largest lists.
That is because retainAll() does a contains() against the list given in the parameter, which is a sequential search, for each element in the intersection list.
Performance can be improved to O(n), where n is the largest list, by converting the lists to sets.
List<String> intersection = new ArrayList<>(lists.get(0));
for (List<String> list : lists.subList(1, lists.size()))
intersection.retainAll(new HashSet<>(list));
In Java 8+, the for loop can be simplified to one of these:
lists.subList(1, lists.size()).stream().map(HashSet::new).forEach(intersection::retainAll);
lists.subList(1, lists.size()).forEach(list -> intersection.retainAll(new HashSet<>(list)));
i would use the list.retainAll method as in
private ArrayList<String> getIntersection(ArrayList<ArrayList<String>> lists) {
if(null == lists || lists.isEmpty()) {
return null;
}
ArrayList<String> intersection = lists.get(0);
lists.forEach(intersection::retainAll);
return intersection;
}
Try this,
ArrayList list1 = new ArrayList{ "cat", "dog" ,"phone", "watch"};
ArrayList list2 = new ArrayList{ "pen", "cat", "dog", "lamp" };
var elements = Enumerable.Intersect(list1.ToArray(), list2.ToArray()).ToArray();
ArrayList result = new ArrayList(elements);
Hope helps,
You can try this:
ArrayList first = new ArrayList();
first.Add("Cat");
first.Add("Dog");
ArrayList second = new ArrayList();
second.Add("Dog");
second.Add("Phone");
ArrayList final = new ArrayList();
foreach (var i in first.Cast<string>().Intersect(second.Cast<string>()))
final.Add(i);
The resulting ArrayList is Dog