下面是什么使不同类型相等的机制?
import static org.testng.Assert.assertEquals;
@Test
public void whyThisIsEqual() {
assertEquals(new HashSet<>(), new ArrayList<>());
}
答案 0 :(得分:55)
assertEquals(Collection<?> actual, Collection<?> expected)
documentation说:
断言两个集合以相同的顺序包含相同的元素。如果没有,则抛出AssertionError。
因此将比较集合的内容,如果两个集合为空,则它们相等。
答案 1 :(得分:31)
他们不是...
System.out.println(new HashSet<>().equals(new ArrayList<>())); // false
这特定于testng
assertEquals
查看该方法的说明文件:
断言两个集合以相同的顺序包含相同的元素。
这对我来说很荒谬,Set
本身没有命令。
Set<String> set = new HashSet<>();
set.add("hello");
set.add("from");
set.add("jug");
System.out.println(set); // [from, hello, jug]
IntStream.range(0, 1000).mapToObj(x -> x + "").forEachOrdered(set::add);
IntStream.range(0, 1000).mapToObj(x -> x + "").forEachOrdered(set::remove);
System.out.println(set); // [jug, hello, from]
因此,在某个特定的时间将它们与Collection
进行比较会产生有趣的结果。
更糟糕的是,java-9
Set::of
方法在内部实现了随机化,因此运行的 order (或顺序)将有所不同。
答案 2 :(得分:9)
Testng调用以这种方式实现的方法。
public static void assertEquals(Collection<?> actual, Collection<?> expected, String message) {
if (actual == expected) {
return;
}
if (actual == null || expected == null) {
if (message != null) {
fail(message);
} else {
fail("Collections not equal: expected: " + expected + " and actual: " + actual);
}
}
assertEquals(
actual.size(),
expected.size(),
(message == null ? "" : message + ": ") + "lists don't have the same size");
Iterator<?> actIt = actual.iterator();
Iterator<?> expIt = expected.iterator();
int i = -1;
while (actIt.hasNext() && expIt.hasNext()) {
i++;
Object e = expIt.next();
Object a = actIt.next();
String explanation = "Lists differ at element [" + i + "]: " + e + " != " + a;
String errorMessage = message == null ? explanation : message + ": " + explanation;
assertEqualsImpl(a, e, errorMessage);
}
}
这试图有所帮助,但由于多种原因而效果不佳。
两个equals集合可能看起来是不同的。
Set<Integer> a = new HashSet<>();
a.add(82);
a.add(100);
System.err.println(a);
Set<Integer> b = new HashSet<>();
for (int i = 82; i <= 100; i++)
b.add(i);
for (int i = 83; i <= 99; i++)
b.remove(i);
System.err.println(b);
System.err.println("a.equals(b) && b.equals(a) is " + (a.equals(b) && b.equals(a)));
assertEquals(a, b, "a <=> b");
和
Set<Integer> a = new HashSet<>();
a.add(100);
a.add(82);
System.err.println(a);
Set<Integer> b = new HashSet<>(32);
b.add(100);
b.add(82);
System.err.println(b);
System.err.println("a.equals(b) && b.equals(a) is " + (a.equals(b) && b.equals(a)));
assertEquals(a, b, "a <=> b");
打印
[82, 100]
[100, 82]
a.equals(b) && b.equals(a) is true
Exception in thread "main" java.lang.AssertionError: a <=> b: Lists differ at element [0]: 100 != 82
at ....
两个集合可以相同也可以不同,这取决于它们的比较方式。
assertEquals(a, (Iterable) b); // passes
assertEquals(a, (Object) b); // passes
assertEquals(Arrays.asList(a), Arrays.asList(b)); // passes
答案 3 :(得分:6)
因为只收集内容,所以不比较收集类型。
其背后的原因是,通常有一些集合的子类是从经过测试的方法返回的,与使用什么子类无关。
答案 4 :(得分:2)
当我运行以下代码时,条件为false
。
if( (new HashSet<>()).equals(new ArrayList<>())){
System.out.println("They are equal");
}
因此assertEquals
, true 是,它仅检查元素及其顺序是否相等。但是对于equals
,它是 false 。