字符串数组作为HashMap的键
我需要解决两个问题,我们的项目,其中(1)我必须找到一种方法,我可以保留一个数组(String []或int [])作为地图。要求是,如果两个数组的内容相同(String [] a = {“A”,“B”},String [] b = {“B”,“A”}),那么它们应该被视为等于/相同的键,即,如果我使用a或b作为Map的键,则a.equal(b)= true字符串数组作为HashMap的键
我发现Java集增加了存储在其中的所有对象的哈希码。散列码的添加允许比较两个哈希集,以查看它们是否相等,这意味着这种机制允许根据其内容比较两个Java集。
因此,对于上述问题,我可以使用套件作为地图的关键,但事情是我想使用数组作为关键。那么对此有何想法? (2)接下来的事情是,我们对高效的部分密钥匹配机制感兴趣。例如,查看Map中的任何键是否包含数组的一部分,例如查找Key.contains(new String [] {“A”})。
请分享您的想法,任何替代方式,我关心空间和时间的最佳实施。这将在数据流处理项目中使用。所以空间和时间确实是一个问题。
我尝试使用lambda表达式在Java8解决您的问题
对于问题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));
如果您想对它们进行比较,如果他们是平等的。我建议你可以先排序然后比较。 当然,这是更好的使用设置和hashCode做comparsion
对于问题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
Q1 - 你不能使用裸数组作为HashMap键,如果你想要基于数组元素的键相等。阵列从java.lang.Object
继承equals(Object)
和hashCode()
实现,它们基于对象标识,而不是阵列内容。
我能想到的最佳选择是将数组包装为(不可变)列表。第二季度 - 我不认为有一个简单有效的方法来做到这一点。我能想到的最好的是:每个数组的
提取出所有可能的子阵列,使每一个哈希表的替代键。问题是密钥将采用
O(N M^2)
空间,其中M
是主键String[]
中字符串的平均(?)数。查找仍然是O(1)
。构建一个倒排索引,给出每个字符串在所有键中的位置,然后对键空间中的字符串序列进行“词组搜索”。这应该在空间使用方面更好地扩展,但是查找会更加昂贵。而且很复杂。
为了方便起见,您可能会更喜欢'Set';这样,你可以保证围绕'equals'和'hashCode'发生的行为。 – Makoto
也参见[能否Java数组被用作一个HashMap键](http://stackoverflow.com/questions/16839182/can-a-java-array-be-used-as-a-hashmap-key)。正如所建议的,你应该使用'Set'来代替,因为你不能覆盖数组的'equals' /'hashCode'的行为。 –
好的,第二个问题呢,有什么想法? – Zubair