字符串数组作为HashMap的键

时间:2015-10-15 23:13:52

标签: java

我需要为我们的项目解决两个问题,其中(1)我必须找到一种方法,我可以将数组(String []或int [])保存为Map的键。要求是,如果两个数组的内容相等(String [] a = {" A"," B"},String [] b = {" B& #34;," A"})然后它们应被视为相等/相同的键,即,如果我使用a或b作为Map的键,则a.equal(b)= true

我发现Java Sets会添加存储在其中的所有对象的哈希码。添加哈希码允许比较两个哈希集,以查看它们是否相等,这意味着这种机制允许基于它们的内容比较两个Java集。

因此对于上述问题,我可以使用Sets作为Map的键,但事实是我想使用Arrays作为Key。那有什么想法吗?

(2)接下来的事情是,我们感兴趣的是一种有效的部分密钥匹配机制。例如,查看Map中的任何键是否包含数组的一部分,例如查找Key.contains之类的内容(new String [] {" A"})。

请分享您的想法,任何替代方式,我关注空间和时间的最佳实施。因为这将用于数据流处理项目。所以空间和时间确实是一个问题。

2 个答案:

答案 0 :(得分:2)

Q1 - 如果您希望基于数组元素的密钥相等,则不能将裸数组用作HashMap密钥。数组继承equals(Object)的{​​{1}}和hashCode()实现,它们基于对象标识,而不是数组内容。

我能想到的最好的选择是将数组包装为(不可变的)列表。

Q2 - 我认为没有一种简单有效的方法可以做到这一点。我能想到的最好的是:

  • 提取每个数组的所有可能的子数组,并使每个数组成为哈希表中的备用键。问题是密钥将占用java.lang.Object空格,其中O(N M^2)是主键M中字符串的平均数(?)。查询仍然是String[]

  • 构建一个倒置索引,给出所有键中每个字符串的位置,然后对键空间中的一系列字符串进行“短语搜索”。这应该在空间使用方面更好地扩展,但查找要贵得多。它很复杂。

答案 1 :(得分:0)

我尝试在Java8中使用lambda表达式来解决你的问题

对于问题1:

    String[] arr1 = {"A","B","A","C","D"};
    List<String> list1 = new ArrayList<String>(new LinkedHashSet<>(Arrays.asList(arr1)));
    list1.stream().forEach(x -> System.out.println(x));

如果您想要比较它们是否相等。我建议你先排序然后比较。 当然,使用Set和Hashcode进行比较会好得多。

对于问题2(上面的某些变量将被重复使用):

    String[] arr2 = {"A"};
    List<String> list2 = new ArrayList<String>(Arrays.asList(arr2)); //Assume List2 element is also unique
    int NumOfKeyContain = list1.stream().filter(a -> (list2.stream().filter(b -> !b.equals(a)).count())<list2.size())
            .collect(Collectors.toList())
            .size();
    System.out.println(NumOfKeyContain); //NumOfKeyContain is the number that of key in list2 contained by list1