【发布时间】:2014-04-28 21:30:32
【问题描述】:
我有一个看起来像这样的对象(我使用了一些 Guava 库来简化我的 equals 和 hashcode 方法):
public class MyClass {
private Collection<Integer> integers;
private Collection<String> strings;
// Getters and Setters...
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MyClass that = (MyClass) o;
return Objects.equal(integers, that.integers) &&
Objects.equal(strings, that.strings);
}
@Override
public int hashCode() {
return Objects.hashCode(integers, strings);
}
}
我遇到的问题是基本上执行此操作的代码(这将是一个典型的测试用例):
// Produce a new instance of MyClass that users ArrayLists.
MyClass expected = new MyClass();
expected.setIntegers(Arrays.asList(1, 2, 3));
expected.setStrings(Arrays.asList("a", "b"));
// I don't normally construct the actual object here,
// but I've included the code so you get an understanding of what's happening
// Produce a new instance of MyClass that uses HashSets.
Set<Integer> someNumbers = new HashSet<Integer>();
someNumbers.add(1);
someNumbers.add(2);
someNumbers.add(3);
Set<String> someStrings = new HashSet<String>();
someStrings.add("a");
someStrings.add("b");
MyClass actual = new MyClass();
actual.setIntegers(someNumbers);
actual.setIntegers(someStrings);
assertEquals(expected, actual);
我遇到的问题是,即使集合的内容都是相同的,并且这些成员的编译时类型是“集合”,运行时类型用于评估相等性,所以这个断言失败。查看 AbstractSet.equals 和 AbstractList.equals 的源代码,他们在评估内容之前分别检查另一个对象是 Set 还是 List。
我认为这是有道理的,因为顺序在列表中很重要,而在集合中不重要,因此,即使内容相同,您也无法比较它们。
也就是说,在这种情况下,我不关心底层集合是什么 - 我只想知道内容是否相同并且顺序没有区别。有什么简单的方法吗?
【问题讨论】:
-
您可以将一个集合的内容复制到
Set<OtherClass>中,然后比较另一个集合的所有元素是否都存在于Set中。 -
@LuiggiMendoza 它不应该是一个集合,它会将两个列表 [1,2] 和 [1,1,2] 视为相等。
-
@amit 这取决于 OP 的要求,即一个集合等于另一个集合。
标签: java collections