Why are empty collections of different type equal?

后端 未结 3 2116
攒了一身酷
攒了一身酷 2021-02-11 12:29

What is mechanism below that makes equal different types?

import static org.testng.Assert.assertEquals;
@Test
public void whyThisIsEq         


        
相关标签:
3条回答
  • 2021-02-11 12:58

    Testng calls through to a method implemented this way.

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

    This is trying to be helpful but is poor for a number of reasons.

    Two equals collections can appear to be different.

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

    and

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

    prints

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

    Two collections can be the same or different depending on how they are compared.

    assertEquals(a, (Iterable) b); // passes
    
    assertEquals(a, (Object) b); // passes
    
    assertEquals(Arrays.asList(a), Arrays.asList(b)); // passes
    
    0 讨论(0)
  • 2021-02-11 13:12

    They are not...

    System.out.println(new HashSet<>().equals(new ArrayList<>())); // false
    

    This is specific to testng assertEquals

    Looking at the documentation of that method it says:

    Asserts that two collections contain the same elements in the same order.

    And this is ridiculous to me, a Set does not have an order, 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]
    

    So comparing these against a Collection at some particular point in time would yield interesting results.

    Even worse, java-9 Set::of methods implement a randomization internally, so the order (or not the order) will be different from run to run.

    0 讨论(0)
  • 2021-02-11 13:17

    The assertEquals(Collection<?> actual, Collection<?> expected) documentation says:

    Asserts that two collections contain the same elements in the same order. If they do not, an AssertionError is thrown.

    Thus the content of the collections will be compared which, in case both the collections are empty, are equal.

    0 讨论(0)
提交回复
热议问题