What you want is called intersection.
See that:
Intersection and union of ArrayLists in Java
The use of an Hash based collection provides a really faster contains() method, particularly on strings which have an optimized hashcode.
If you can import libraries you can consider using the Sets.intersection of Guava.
Edit:
Didn't know about the retainAll method.
Note that the AbstractCollection implementation, which seems not overriden for HashSets and LinkedHashSets is:
public boolean retainAll(Collection c) {
boolean modified = false;
Iterator it = iterator();
while (it.hasNext()) {
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
Which means you call contains() on the collection parameter!
Which means if you pass a List parameter you will have an equals call on many item of the list, for every iteration!
This is why i don't think the above implementations using retainAll are good.
public <T> List<T> intersection(List<T> list1, List<T> list2) {
boolean firstIsBigger = list1.size() > list2.size();
List<T> big = firstIsBigger ? list1:list2;
Set<T> small = firstIsBigger ? new HashSet<T>(list2) : new HashSet<T>(list1);
return big.retainsAll(small)
}
Choosing to use the Set for the smallest list because it's faster to contruct the set, and a big list iterates pretty well...
Notice that one of the original list param may be modified, it's up to you to make a copy...