我需要为我们的项目解决两个问题,其中(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"})。
请分享您的想法,任何替代方式,我关注空间和时间的最佳实施。因为这将用于数据流处理项目。所以空间和时间确实是一个问题。
答案 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