Reputation: 2066
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());
Upvotes: 0
Views: 3844
Reputation: 39
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);
}
Upvotes: 0
Reputation: 3036
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.
Upvotes: 1
Reputation: 18633
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.
Upvotes: 0