Finding out the indices of common elements in two array lists having duplicate elements I have two lists which are also  having some duplicate elements , i am converting this list to map as key value pair with element index as the value for the key - element 

List 1 : [1, 2, 3, 4, 5, 6, 7, 2] = > 

MAP 1 (Map, List>) : {1=[0], 2=[1, 7], 3=[2], 4=[3], 5=[4], 6=[5], 7=[6]} 

List 2 : [3, 3, 2, 4, 7] 

= > MAP 2 (Map, List>) : {2=[2], 3=[0, 1], 4=[3], 7=[4]}

i am trying to collect matching keys from both of the maps and club it another map 

For above two it would give the result : {[2]=[0, 1], [3]=[3], [6]=[4], [1, 7]=[2]}

Post this , i am taking the cartesian product of key , values and only retaining the unique elements 

Final output [[0, 2], [1, 2], [3, 3], [4, 6], [2, 1], [2, 7]] . These is the indices of common elements 

Below is the code that i have come up with to achieve this , is there any better way i can achieve the same . I feel it will be too much costly at run time for larger lists . 


 List&lt;List&lt;Integer&gt;&gt; cartesianProduct = new ArrayList&lt;&gt;();
 List&lt;String&gt; distinct1 = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "2")
 List&lt;String&gt; distinct2 = Arrays.asList["3", "3", "2", "4", "7"] 

 Map&lt;String, List&lt;Integer&gt;&gt; result1 = IntStream.range(0, distinct1.size()).boxed()
                     .collect(Collectors.groupingBy(i -&gt; distinct1.get(i)));

 Map&lt;String, List&lt;Integer&gt;&gt; result2 = IntStream.range(0, distinct2.size()).boxed()
                    .collect(Collectors.groupingBy(i -&gt; distinct2.get(i)));

 result1.entrySet().stream()
                    .filter(x -&gt; result2.containsKey(x.getKey()))
                    .collect(Collectors.toMap(x -&gt; x.getValue(), x -&gt; result2.get(x.getKey())))
                    .entrySet().forEach(a1 -&gt; a1.getValue().stream()
                    .forEach(b1 -&gt; a1.getKey().stream().forEach(c1 -&gt; cartesianProduct.add(Arrays.asList(b1, c1)))));

   List&lt;List&lt;Integer&gt;&gt; listWithoutDuplicates = cartesianProduct.stream()
           .distinct()
           .collect(Collectors.toList());
Firstly, try to make sure that code you post here compiles. Now you have missing semicolons on the lines

List&lt;String&gt; distinct1 = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "2")
List&lt;String&gt; distinct2 = Arrays.asList["3", "3", "2", "4", "7"] 


and also the last of these two lines has [...] instead of (...).

It was also a bit difficult to actually figure out what your code was supposed to do, but I think I understand it now.

It seems you want to create a list of pairs of some sort. So instead of ending with a List&lt;List&lt;Integer&gt;&gt;, you can create a Pair class

public final class Pair&lt;S, T&gt; {
  private final S left;
  private final T right;

  public Pair(S left, T right) {
    this.left = left;
    this.right = right;
  }

  public S left() {
    return left;
  }

  public T right() {
    return right;
  }

  // equals and hashCode
  ...
}


and have a List&lt;Pair&lt;Integer, Integer&gt;&gt; instead.

Then you can create a method which given two Lists creates the cartesian product

public List&lt;Pair&lt;S, T&gt;&gt; cartesianProduct(List&lt;S&gt; firstList, List&lt;T&gt; secondList) {
  return firstList.stream()
    .flatMap(x -&gt; secondList.stream().map(y -&gt; new Pair&lt;&gt;(x, y)))
    .collect(Collectors.toList());
}


During the construction of your cartesian list, you collect your intermediate results into a Map. This step is not needed as you can now immediately convert to a list of pairs. Also, it is usually not a good idea to have a List as keys of a Map as the List is mutable. Map expects the hash code of the keys to not change which is a possibility when using Lists as keys.

Removing the Map step in the process we get

List&lt;Pair&lt;Integer, Integer&gt;&gt; listWithoutDuplicates = result1.entrySet().stream()
        .filter(x -&gt; result2.containsKey(x.getKey()))
        .flatMap(x -&gt; cartesianProducts(result2.get(x.getKey()), x.getValue()).stream())
        .distinct()
        .collect(Collectors.toList());