0

I need to find the intersection between 2 hash maps where the value is a String array, It seems that the retainAll() compares arrays by address, Is there any way to make retainAll() works that way I expected?

String[] aa={"aa"};
String[] bb={"aa"};
Map<String, String[]> requestParameters=new HashMap<String, String[]>();
requestParameters.put("A",aa);
Map<String, String[]> redirectParameters=new HashMap<String, String[]>();
redirectParameters.put("A",bb);

Map<String, String[]> intersectionMap = new HashMap<>(requestParameters);
intersectionMap.entrySet().retainAll(redirectParameters.entrySet());
System.out.println(""+ intersectionMap.entrySet());
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
Arar
  • 1,926
  • 5
  • 29
  • 47
  • 1
    Please don't tag Java code as Javascript code snippets - they're not. – Jon Skeet Jun 10 '16 at 15:52
  • Can you elaborate on the background of the problem? A map of arrays seems a bit unusual. Are you restricted to solving your problem this way? – Tim Biegeleisen Jun 10 '16 at 15:53
  • Sure, I am trying to find the intersection between the request.getParameterMap() and a list of possible redirect cases. request.getParameterMap() --> Map – Arar Jun 10 '16 at 16:03

3 Answers3

1

The retainAll() method compares objects using their equals() method, which in the case of arrays compares their identities. The entry object just calls the key's and value's equal methods in its equals method and thus just calls the arrays equal method which doesn't work as one would expect. There are multiple ways to get around this problem:

One way would be to use Guanva's filter as described in andersoj answer here.

Another way would be to create a wrapper class for your string arrays that overwrites the equals method of this wrapper to compare the two arrays element by element. This was also described in the answer by Ralph to the same question as before.

If you want to get around the wrapper you can also use lists, as their equals method is implemented as you would expect. It will return true if both lists contain the same elements in the same order.

Community
  • 1
  • 1
Leon
  • 2,926
  • 1
  • 25
  • 34
0

Could wrap the array:

import java.util.*;

class Test {

  private static class StringArrayWrapper {

    private String[] data;

    public String[] getArray() {
      return data;
    }

    public StringArrayWrapper(String[] data) {
      this.data = data;
    }

    public boolean equals(Object other) {
      return (other instanceof StringArrayWrapper) && Arrays.equals(data, ((StringArrayWrapper)other).data);
    }

    public String toString() {
      return Arrays.toString(data);
    }

    public int hashCode() {
      return Arrays.hashCode(data);
   }

  }

  private static StringArrayWrapper wrap(String[] a) {
    return new StringArrayWrapper(a);
  }


  public static void main(String[]args) {
    String[] aa={"aa"};
    String[] bb={"aa"};
    Map<String, StringArrayWrapper> requestParameters=new HashMap<String, StringArrayWrapper>();
    requestParameters.put("A", wrap(aa));
    Map<String, StringArrayWrapper> redirectParameters=new HashMap<String, StringArrayWrapper>();
    redirectParameters.put("A", wrap(bb));

    Map<String, StringArrayWrapper> intersectionMap = new HashMap<>(requestParameters);
    intersectionMap.entrySet().retainAll(redirectParameters.entrySet());
    System.out.println(""+ intersectionMap.entrySet());
  }
}

This prints:

[A=[aa]]

But normally, you'd want to intersect maps by key, like here.

Community
  • 1
  • 1
Vlad
  • 18,195
  • 4
  • 41
  • 71
0

try used this

static void intersection(String[]...inputArrays){
       HashSet<String> intersectionSet = new HashSet<>(Arrays.asList(inputArrays[0]));
       int a=0;
        for (int i = 1; i< inputArrays.length;i++){
            HashSet<String> set = new HashSet<>(Arrays.asList(inputArrays[i]));
            intersectionSet.retainAll(set);
        }
        System.out.println("======================");
        System.out.println("Interseksi nya");
        System.out.println("======================");
        System.out.println(intersectionSet);

    }
    public void test(){
        String[] inputArray1 = { "aku","kamu","dia","mereka"};
        String[] inputArray2 = {"dia","saya","mereka","aku"};
        String[] inputArray3 = {"aku","mereka","kita","dia"};        
        intersection(inputArray1,inputArray2,inputArray3);
    }

enter image description here

Wahyudi
  • 39
  • 5