Assuming that the given lists should not be changed by removing elements or sorting them (which has O(nlogn) complexity, by the way), you basically need one function as a "building block" for the actual solution. Namely, a function that checks whether one collection contains any element that is contained in another collection.
Of course, this can be solved by using Collection#contains
on the second collection. But for some collections (particularly, for lists), this has O(n), and the overall running time of the check would be O(n*n).
To avoid this, you can create a Set
that contains all elements of the second collection. For a Set
, the contains
method is guaranteed to be O(1).
Then, the actual check can be done conveniently, with Stream#anyMatch
:
containing.stream().anyMatch(e -> set.contains(e))
So the complete example could be
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class DuplicatesInLinkedLists
{
public static void main(String[] args)
{
LinkedList<LinkedList<String>> lls =
new LinkedList<LinkedList<String>>();
LinkedList<String> list1 =
new LinkedList<String>(Arrays.asList("dog", "cat", "snake"));
LinkedList<String> list2 =
new LinkedList<String>(Arrays.asList("donkey", "fox", "dog"));
LinkedList<String> list3 =
new LinkedList<String>(Arrays.asList("horse", "cat", "pig"));
lls.add(list1);
lls.add(list2);
lls.add(list3);
checkDuplicates(lls);
}
private static void checkDuplicates(
List<? extends Collection<?>> collections)
{
for (int i = 0; i < collections.size(); i++)
{
for (int j = i + 1; j < collections.size(); j++)
{
Collection<?> ci = collections.get(i);
Collection<?> cj = collections.get(j);
boolean b = containsAny(ci, cj);
System.out.println(
"Collection " + ci + " contains any of " + cj + ": " + b);
}
}
}
private static boolean containsAny(Collection<?> containing,
Collection<?> contained)
{
Set<Object> set = new LinkedHashSet<Object>(contained);
return containing.stream().anyMatch(e -> set.contains(e));
}
}
A side note: The code that you posted almost certainly does not make sense in the current form. The declaration and creation of the lists should usually rely on List
:
List<List<String>> lists = new ArrayList<List<String>>();
lists.add(Arrays.asList("dog", "cat", "snake");
...
If the elements of the list have to me modifiable, then you could write
lists.add(new ArrayList<String>(Arrays.asList("dog", "cat", "snake"));
or, analogously, use LinkedList
instead of ArrayList
, but for the sketched use case, I can't imagine why there should be a strong reason to deliberately use LinkedList
at all...