用java实现通用映射
问题描述:
我知道你可以通过一个对象向某个方法传递任何东西。我正在尝试编写一个断言函数来检查两个地图是否相等。我不能只使用map1.equals(map2),因为即使它们具有所有相同的键和值,它们也可能以不同的顺序排列。所以我想通过第一张地图上的每个键来获得它的价值,并将其与第二张地图中该键的价值进行比较。我想通常这样做。所以我写的(这是不大不小的存根,以证明我的问题,我会做更多的空检查,等等。):用java实现通用映射
public void assertMapEquals(Map<Object, Object> f, Map<Object, Object> l) {
// This will do null checks, don't worry
for (Entry<Object, Object> ent : f.entrySet()) {
if (f.size() != l.size()) {
throw new AssertionError ("size mismatch");
}
Object k = ent.getKey();
Object e = ent.getValue();
Object a = l.get(k);
if (!e.equals(a)) {
throw new AssertionError("unequal");
}
}
}
然后我试着用两个String映射到调用它:
public static void main(String[] argv) throws SQLException {
Map<String,String> m1 = new HashMap<>();
Map<String,String> m2 = new HashMap<>();
// Data will get filled in later
assertMapEquals(m1, m2);
// ...
}
但是Eclipse是给我下面的错误上的呼叫:
在 的方法assertMapEquals(地图,地图)类型MyMain1不适用于参数 (地图,地图)
不是字符串对象,所以为什么不能这样工作,我该怎么办?这个问题可以应用于这种类型的任何示例,而不仅仅是比较两张地图。
我还有一个额外的问题是有没有更好的方法可以做到这一点,但它并不关心订单?
答
您可以使用paramethized通用的方法,通过<?, ?>
(不<K, V>
,因为在注释中提到也可以是不同类型的,仍然相等,如Map<String, String>
VS Map<Object, Object>
):
public static void assertMapEquals(Map<?, ?> f, Map<?, ?> l) {
if (f == null || l == null)
throw new NullPointerException();
if (f.size() != l.size())
throw new AssertionError ("size mismatch");
for (Entry<?, ?> ent : f.entrySet()) {
Object k = ent.getKey();
Object e = ent.getValue();
Object a = l.get(k);
if (!Objects.equals(e, a)) // handle null values
throw new AssertionError("unequal");
}
}
其他方法将只是直接比较地图:
public static void assertMapEquals(Map<?, ?> f, Map<?, ?> l) {
if (f == null || l == null)
throw new NullPointerException();
if (f.size() != l.size())
throw new AssertionError("size mismatch");
if (!f.equals(l))
throw new AssertionError("unequal contents");
}
通过合同,Map#equals(Object o)
返回true iff o
是Map
,它有相同的内容。
为什么不使用'assertMapEquals(Map,Map )'? –
tumisma
这就是我改变它,但它是可以想象的,我想打电话给它有时与其他类型的地图。 – Tony
只有在使用'TreeMap'时才能保证订购。任何其他的'Map'都不会保留密钥的排序 –