setlayout - manejo de gridlayout en java
¿Por qué son iguales las colecciones vacías de diferente tipo? (5)
Cuando corro debajo del código, la condición es
false
.
if( (new HashSet<>()).equals(new ArrayList<>())){
System.out.println("They are equal");
}
Por lo tanto, para
assertEquals
, es
cierto
que solo verifica los elementos y su orden de igualdad.
Pero para los
equals
es
falso
.
¿Cuál es el mecanismo a continuación que hace que los diferentes tipos sean iguales?
import static org.testng.Assert.assertEquals;
@Test
public void whyThisIsEqual() {
assertEquals(new HashSet<>(), new ArrayList<>());
}
Ellos no son...
System.out.println(new HashSet<>().equals(new ArrayList<>())); // false
Esto es específico para
testng
assertEquals
Mirando la documentación de ese método dice:
Afirma que dos colecciones contienen los mismos elementos en el mismo orden.
Y esto es ridículo para mí, un
Set
no tiene una orden, per-se.
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]
Por lo tanto, compararlos con una
Collection
en
algún
momento
particular
en el tiempo daría resultados interesantes.
Lo que es peor, el
Set::of
métodos
java-9
implementa una aleatorización internamente, por lo que el
orden
(o no el orden) será diferente de una ejecución a otra.
La documentación de
assertEquals(Collection<?> actual, Collection<?> expected)
dice:
Afirma que dos colecciones contienen los mismos elementos en el mismo orden. Si no lo hacen, se lanza un error de afirmación.
Por lo tanto, se comparará el contenido de las colecciones que, en caso de que ambas colecciones estén vacías, son iguales.
Porque para la colección solo se compara el contenido, no el tipo de colección.
La razón detrás de esto es que a menudo se devuelve alguna subclase de colección desde el método probado y es irrelevante lo que se usa exactamente subclase.
Testng llama a través de un método implementado de esta manera.
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);
}
}
Esto intenta ser útil, pero es deficiente por varias razones.
Dos colecciones iguales pueden parecer diferentes.
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");
y
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");
huellas dactilares
[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 ....
Dos colecciones pueden ser iguales o diferentes dependiendo de cómo se comparan.
assertEquals(a, (Iterable) b); // passes
assertEquals(a, (Object) b); // passes
assertEquals(Arrays.asList(a), Arrays.asList(b)); // passes