用java实现通用映射

用java实现通用映射,java,Java,我知道,您可以将几乎任何内容传递给带有对象的方法。我试图编写一个assert函数来检查两个映射是否相等。我不能只使用map1.equals(map2),因为即使它们具有所有相同的键和值,它们的顺序也可能不同。所以我想遍历第一个映射中的每个键,得到它的值,并将它与第二个映射中该键的值进行比较。我想一般地做。所以我写了这个(这是一个存根来证明我的问题。我会做更多的空检查,等等): public void assertMapEquals(图f、图l){ //这将进行空检查,不用担心 对于(Entry-

我知道,您可以将几乎任何内容传递给带有对象的方法。我试图编写一个assert函数来检查两个映射是否相等。我不能只使用map1.equals(map2),因为即使它们具有所有相同的键和值,它们的顺序也可能不同。所以我想遍历第一个映射中的每个键,得到它的值,并将它与第二个映射中该键的值进行比较。我想一般地做。所以我写了这个(这是一个存根来证明我的问题。我会做更多的空检查,等等):

public void assertMapEquals(图f、图l){
//这将进行空检查,不用担心
对于(Entry-ent:f.entrySet()){
如果(f.size()!=l.size()){
抛出新断言错误(“大小不匹配”);
}       
对象k=ent.getKey();
对象e=ent.getValue();
对象a=l.get(k);
如果(!e等于(a)){
抛出新断言错误(“不平等”);
}       
}
}
然后我尝试用两个字符串映射调用它:

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);
    // ...
 }
publicstaticvoidmain(字符串[]argv)抛出SQLException{
Map m1=新的HashMap();
Map m2=新的HashMap();
//数据将在以后填写
资产映射等于(m1,m2);
// ...
}
但是Eclipse在调用中给了我以下错误:

中的方法assertMapEquals(Map,Map) MyMain1类型不适用于参数 (地图,地图)

字符串不是对象,那么为什么这不起作用,我该怎么办?这个问题可以应用于这类的任何例子,而不仅仅是比较两张地图


另外一个问题是,在比较但不关心顺序的情况下,有没有更好的方法可以做到这一点?

您可以使用由
参数化的通用方法(而不是
,因为如注释中所述,它们可能是不同类型的,并且仍然相同,例如
Map
Map
):

publicstaticvoidassertmapequals(Map f,Map l){
如果(f==null | | l==null)
抛出新的NullPointerException();
如果(f.size()!=l.size())
抛出新断言错误(“大小不匹配”);
对于(Entry-ent:f.entrySet()){
对象k=ent.getKey();
对象e=ent.getValue();
对象a=l.get(k);
如果(!Objects.equals(e,a))//处理空值
抛出新断言错误(“不平等”);
}
}
另一种方法是直接比较地图:

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");
}
publicstaticvoidassertmapequals(Map f,Map l){
如果(f==null | | l==null)
抛出新的NullPointerException();
如果(f.size()!=l.size())
抛出新断言错误(“大小不匹配”);
如果(!f等于(l))
抛出新断言错误(“不平等内容”);
}

根据合同,
Map#equals(Object o)
返回真正的iff
o
Map
,具有相同的内容。

您可以使用由
参数化的通用方法(而不是
),因为如注释中所述,它们可能是不同类型的,并且仍然相同,例如
Map
vs
Map
):

publicstaticvoidassertmapequals(Map f,Map l){
如果(f==null | | l==null)
抛出新的NullPointerException();
如果(f.size()!=l.size())
抛出新断言错误(“大小不匹配”);
对于(Entry-ent:f.entrySet()){
对象k=ent.getKey();
对象e=ent.getValue();
对象a=l.get(k);
如果(!Objects.equals(e,a))//处理空值
抛出新断言错误(“不平等”);
}
}
另一种方法是直接比较地图:

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");
}
publicstaticvoidassertmapequals(Map f,Map l){
如果(f==null | | l==null)
抛出新的NullPointerException();
如果(f.size()!=l.size())
抛出新断言错误(“大小不匹配”);
如果(!f等于(l))
抛出新断言错误(“不平等内容”);
}

根据约定,
Map#equals(Object o)
返回真正的iff
o
is
Map
,它具有相同的内容。

为什么不使用
assertMapEquals(Map,Map)
?这就是我将其更改为的内容,但这是可以想象的,有时我想用其他类型的地图来称呼它。只有在使用
TreeMap
时才能保证排序。任何其他
Map
都不会保留键的顺序为什么要检查
f.size()!=l、 每次迭代时使用size()
?这个检查应该在foreach之外完成。我不明白你为什么不使用
AbstractMap.equals()
。从JavaDoc for
AbstractMap
-“更正式地说,如果m1.entrySet().equals(m2.entrySet()),两个映射m1和m2表示相同的映射。”。这应该是顺序独立的,听起来与您试图实现的完全一样。为什么不使用
assertMapEquals(Map,Map)
?这就是我将其更改为的内容,但可以想象的是,有时我会将其与其他类型的映射一起调用。只有在使用
TreeMap
时,才能保证顺序。任何其他
Map
都不会保留键的顺序为什么要检查
f.size()!=l、 每次迭代时使用size()
?这个检查应该在foreach之外完成。我不明白你为什么不使用
AbstractMap.equals()
。从JavaDoc for
AbstractMap
-“更正式地说,如果m1.entrySet().equals(m2.entrySet()),两个映射m1和m2表示相同的映射。”。这应该是顺序独立的,并且听起来和您试图实现的完全一样。
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");
}