想象一下我有两张地图:
HashMap<TestClass, Integer> map1, map2;
假设TestClass已经定义为:
class TestClass {
int i;
public TestClass(int i){
this.i = i;
}
}
以下代码用于填充地图:
map1.put(new TestClass(1), 1);
map1.put(new TestClass(2), 2);
map2.put(new TestClass(1), 1);
map2.put(new TestClass(2), 2);
我希望编写一个方法,如果两个映射包含“相同”的键和值,则返回
true
。在上面的示例中,我可以创建一个本地变量来存储第一个构造函数调用的结果并将其传递给第二个映射,但在我的实际应用程序中我不能这样做,因为我想比较不相等的相似对象,至少就Java的equals
方法实现而言。我之前的实现(简化):
if(map1.size() == map2.size()){
for(String key1 : map1.keySet()){
if(!map1.get(key1).equals(map2.get(key1))
return false;
}
return true;
} else
return false;
对于String
来说,这很好用,因为即使在不同的位置实例化两次,它们也是相等的。
但是,执行TestClass的构造函数两次会返回两个不同的对象,因此map2.get(key1)
将返回null(或抛出异常,我不是完全确定),因为key1
不在map2
中。
为了比较两个映射,我编写了以下代码(简化):
if(map1.size() == map2.size()){
for(TestClass key1 : map1.keySet()){
boolean foundEqualing = false;
for (TestClass key2 : map2.keySet()) {
// Search equaling
if (key1.i == key2.i) {
// Check if corresponding values equal as well
if (map1.get(key1).equals(map2.get(key2))
// Store that a equaling key value pair was found
foundEqualing = true;
// Break if keys equaled each other
break;
}
}
// Return false if no equaling key was found or if keys equal each other but the corresponding values don't
if (!foundEqualing)
return false;
}
return true;
} else
return false;
我对这段代码的问题在于它循环遍历了两个映射表,这对效率来说似乎非常低下。我不熟悉正确的标记符号,但是如果我没有弄错的话,操作所需时间会随着地图大小的加倍而增加四倍。
除了编写for循环之外,是否有更有效的方式来循环或过滤这些映射表呢?
我的真实代码使用反射,因此不要过分关注提供的示例。映射表的类型可能来自任何类型(唯一我知道的是它们必须实现某个接口,否则它们将被忽略)。
编辑:
我目前正在考虑使用流筛选收集语法,但我从未使用过。它是否更有效,还是内部也只是循环遍历映射表?