52 votes

Pourquoi les collections vides de type différent sont-elles égales?

Quel est le mécanisme ci-dessous qui rend les types différents égaux?

 import static org.testng.Assert.assertEquals;
 @Test
public void whyThisIsEqual() {
    assertEquals(new HashSet<>(), new ArrayList<>());
}

55voto

S.K. Points 2527

Le assertEquals(Collection<?> actual, Collection<?> expected) documentation dit:

Affirme que deux collections contiennent les mêmes éléments dans le même ordre. Si ce n'est pas le cas, une AssertionError est levée.

Ainsi, le contenu des collections sera comparé qui, dans le cas où les deux collections sont vides, sont égaux.

9voto

Peter Lawrey Points 229686

Testng fait appel à une méthode implémentée de cette manière.

   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);
    }
  }

Cela essaie d'être utile mais est médiocre pour un certain nombre de raisons.

Deux collections égales peuvent sembler différentes.

 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");

et

 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");

impressions

 [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 ....

Deux collections peuvent être identiques ou différentes selon la manière dont elles sont comparées.

 assertEquals(a, (Iterable) b); // passes

assertEquals(a, (Object) b); // passes

assertEquals(Arrays.asList(a), Arrays.asList(b)); // passes

6voto

talex Points 7172

Parce que pour la collection, seul le contenu est comparé, pas le type de collection.

La justification derrière cela est que souvent une sous-classe de collection est renvoyée par la méthode testée et que la sous-classe exacte est utilisée.

2voto

Raj Points 657

Lorsque j'exécute sous le code, la condition est false .

 if( (new HashSet<>()).equals(new ArrayList<>())){
            System.out.println("They are equal");
        }

Donc pour assertEquals , il est vrai qu'il ne vérifie que les éléments et son ordre d'égalité. Mais pour equals c'est faux .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X