【问题标题】:Find the intersection between hashmaps using retainAll()使用 retainAll() 查找哈希图之间的交集
【发布时间】:2016-06-10 15:48:56
【问题描述】:

我需要找到值是字符串数组的 2 个哈希映射之间的交集,似乎 retainAll() 按地址比较数组,有没有办法让 retainAll() 按我预期的方式工作?

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());

【问题讨论】:

  • 请不要将 Java 代码标记为 Javascript 代码 sn-ps - 它们不是。
  • 能否详细说明问题的背景?数组映射似乎有点不寻常。您是否仅限于以这种方式解决您的问题?
  • 当然,我试图找到 request.getParameterMap() 和可能的重定向案例列表之间的交集。 request.getParameterMap() --> Map

标签: java arrays


【解决方案1】:

retainAll() 方法使用它们的equals() 方法比较对象,在数组的情况下该方法比较它们的身份。入口对象只是在its equals method 中调用键和值的equal 方法,因此只是调用了数组equal 方法,这并不像预期的那样工作。有多种方法可以解决这个问题:

一种方法是使用 Guanva's filter,如 andersoj answer here 中所述。

另一种方法是为您的字符串数组创建一个包装器类,该类覆盖此包装器的 equals 方法,以逐个元素地比较两个数组。这也在answer by Ralph 中对与以前相同的问题进行了描述。

如果您想绕过包装器,您也可以使用列表,因为 their equals method 的实现方式如您所愿。如果两个列表以相同的顺序包含相同的元素,它将返回 true。

【讨论】:

    【解决方案2】:

    可以包装数组:

    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());
      }
    }
    

    打印出来:

    [A=[aa]]
    

    但通常情况下,您会希望按键与地图相交,例如 here

    【讨论】:

    • 为什么要创建一个自定义类来包装数组,而不是使用 Arrays.asList 已经可以满足您的需求?
    【解决方案3】:

    试试这个

    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);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-17
      • 1970-01-01
      • 2017-01-12
      • 1970-01-01
      • 2020-06-07
      • 2019-10-01
      • 2015-03-06
      • 1970-01-01
      相关资源
      最近更新 更多