Why are empty collections of different type equal?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
33
down vote

favorite
3












What is mechanism below that makes equal different types?



import static org.testng.Assert.assertEquals;




@Test
public void whyThisIsEqual()
assertEquals(new HashSet<>(), new ArrayList<>());







share|improve this question


























    up vote
    33
    down vote

    favorite
    3












    What is mechanism below that makes equal different types?



    import static org.testng.Assert.assertEquals;




    @Test
    public void whyThisIsEqual()
    assertEquals(new HashSet<>(), new ArrayList<>());







    share|improve this question
























      up vote
      33
      down vote

      favorite
      3









      up vote
      33
      down vote

      favorite
      3






      3





      What is mechanism below that makes equal different types?



      import static org.testng.Assert.assertEquals;




      @Test
      public void whyThisIsEqual()
      assertEquals(new HashSet<>(), new ArrayList<>());







      share|improve this question














      What is mechanism below that makes equal different types?



      import static org.testng.Assert.assertEquals;




      @Test
      public void whyThisIsEqual()
      assertEquals(new HashSet<>(), new ArrayList<>());









      share|improve this question













      share|improve this question




      share|improve this question








      edited Sep 6 at 14:26









      Konrad Rudolph

      384k997551008




      384k997551008










      asked Sep 6 at 10:16









      Bartek Wichowski

      434416




      434416






















          5 Answers
          5






          active

          oldest

          votes

















          up vote
          41
          down vote



          accepted










          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.






          share|improve this answer





























            up vote
            25
            down vote













            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.






            share|improve this answer


















            • 5




              I find that a dangerous choice from junit to call assetEquals but not use Object.equals... this lead to "unexpected" behavior like this one.
              – AxelH
              Sep 6 at 10:22











            • @AxelH indeed, I was really not expecting this
              – Eugene
              Sep 6 at 10:23










            • Junit throws an AssertionError here. It is testng which has this behaviour. (I see you edited your answer right when I posted this comment)
              – marstran
              Sep 6 at 10:24











            • @marstran see another edit, I find this a very very weird
              – Eugene
              Sep 6 at 10:34






            • 3




              @AxelH & Eugene, I agree, this method is misnamed. This should be named something like assertEqualContentsOrdered. It would be useful for comparing a list and a set, in the case that you know that the set is ordered. (There is already assertEqualsNoOrder but it only takes arrays.)
              – Stuart Marks
              Sep 6 at 16:37

















            up vote
            7
            down vote













            Testng calls through to a method implemented this way.



             public static void assertEquals(Collection<?> actual, Collection<?> expected, String message) 


            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





            share|improve this answer






















            • It's calling this overload: github.com/cbeust/testng/blob/master/src/main/java/org/testng/…
              – marstran
              Sep 6 at 10:27










            • @marstran ouch, so the type of the reference rather than the object changes the behaviour.
              – Peter Lawrey
              Sep 6 at 10:30






            • 1




              Yep. The overload should have another name imho. Like assertSameElements or something.
              – marstran
              Sep 6 at 10:35










            • @marstran or assertEquals(Object,Object) should check at runtime but even then it's really only good for List not Set
              – Peter Lawrey
              Sep 6 at 10:45







            • 3




              @AxelH This function is bad other reasons, but that fact that it considers null == null is perfectly consistent with the rest of the language.
              – Todd Sewell
              Sep 6 at 11:53

















            up vote
            5
            down vote













            Because for collection only content is compared, not collection type.



            Rationale behind it is that often some subclass of collection is returned from tested method and is irrelevant what exactly subclass is used.






            share|improve this answer



























              up vote
              2
              down vote













              When I run below code the condition is false.



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



              Hence for assertEquals, it is true that it only checks elements and its order for equality. But for equals it is false.






              share|improve this answer




















                Your Answer





                StackExchange.ifUsing("editor", function ()
                StackExchange.using("externalEditor", function ()
                StackExchange.using("snippets", function ()
                StackExchange.snippets.init();
                );
                );
                , "code-snippets");

                StackExchange.ready(function()
                var channelOptions =
                tags: "".split(" "),
                id: "1"
                ;
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function()
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled)
                StackExchange.using("snippets", function()
                createEditor();
                );

                else
                createEditor();

                );

                function createEditor()
                StackExchange.prepareEditor(
                heartbeatType: 'answer',
                convertImagesToLinks: true,
                noModals: false,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                );



                );













                 

                draft saved


                draft discarded


















                StackExchange.ready(
                function ()
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52201814%2fwhy-are-empty-collections-of-different-type-equal%23new-answer', 'question_page');

                );

                Post as a guest






























                5 Answers
                5






                active

                oldest

                votes








                5 Answers
                5






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                41
                down vote



                accepted










                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.






                share|improve this answer


























                  up vote
                  41
                  down vote



                  accepted










                  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.






                  share|improve this answer
























                    up vote
                    41
                    down vote



                    accepted







                    up vote
                    41
                    down vote



                    accepted






                    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.






                    share|improve this answer














                    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.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Sep 6 at 14:46









                    Aaron

                    13.8k11434




                    13.8k11434










                    answered Sep 6 at 10:21









                    S.K.

                    1,157616




                    1,157616






















                        up vote
                        25
                        down vote













                        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.






                        share|improve this answer


















                        • 5




                          I find that a dangerous choice from junit to call assetEquals but not use Object.equals... this lead to "unexpected" behavior like this one.
                          – AxelH
                          Sep 6 at 10:22











                        • @AxelH indeed, I was really not expecting this
                          – Eugene
                          Sep 6 at 10:23










                        • Junit throws an AssertionError here. It is testng which has this behaviour. (I see you edited your answer right when I posted this comment)
                          – marstran
                          Sep 6 at 10:24











                        • @marstran see another edit, I find this a very very weird
                          – Eugene
                          Sep 6 at 10:34






                        • 3




                          @AxelH & Eugene, I agree, this method is misnamed. This should be named something like assertEqualContentsOrdered. It would be useful for comparing a list and a set, in the case that you know that the set is ordered. (There is already assertEqualsNoOrder but it only takes arrays.)
                          – Stuart Marks
                          Sep 6 at 16:37














                        up vote
                        25
                        down vote













                        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.






                        share|improve this answer


















                        • 5




                          I find that a dangerous choice from junit to call assetEquals but not use Object.equals... this lead to "unexpected" behavior like this one.
                          – AxelH
                          Sep 6 at 10:22











                        • @AxelH indeed, I was really not expecting this
                          – Eugene
                          Sep 6 at 10:23










                        • Junit throws an AssertionError here. It is testng which has this behaviour. (I see you edited your answer right when I posted this comment)
                          – marstran
                          Sep 6 at 10:24











                        • @marstran see another edit, I find this a very very weird
                          – Eugene
                          Sep 6 at 10:34






                        • 3




                          @AxelH & Eugene, I agree, this method is misnamed. This should be named something like assertEqualContentsOrdered. It would be useful for comparing a list and a set, in the case that you know that the set is ordered. (There is already assertEqualsNoOrder but it only takes arrays.)
                          – Stuart Marks
                          Sep 6 at 16:37












                        up vote
                        25
                        down vote










                        up vote
                        25
                        down vote









                        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.






                        share|improve this answer














                        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.







                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Sep 6 at 10:43

























                        answered Sep 6 at 10:21









                        Eugene

                        59.4k980139




                        59.4k980139







                        • 5




                          I find that a dangerous choice from junit to call assetEquals but not use Object.equals... this lead to "unexpected" behavior like this one.
                          – AxelH
                          Sep 6 at 10:22











                        • @AxelH indeed, I was really not expecting this
                          – Eugene
                          Sep 6 at 10:23










                        • Junit throws an AssertionError here. It is testng which has this behaviour. (I see you edited your answer right when I posted this comment)
                          – marstran
                          Sep 6 at 10:24











                        • @marstran see another edit, I find this a very very weird
                          – Eugene
                          Sep 6 at 10:34






                        • 3




                          @AxelH & Eugene, I agree, this method is misnamed. This should be named something like assertEqualContentsOrdered. It would be useful for comparing a list and a set, in the case that you know that the set is ordered. (There is already assertEqualsNoOrder but it only takes arrays.)
                          – Stuart Marks
                          Sep 6 at 16:37












                        • 5




                          I find that a dangerous choice from junit to call assetEquals but not use Object.equals... this lead to "unexpected" behavior like this one.
                          – AxelH
                          Sep 6 at 10:22











                        • @AxelH indeed, I was really not expecting this
                          – Eugene
                          Sep 6 at 10:23










                        • Junit throws an AssertionError here. It is testng which has this behaviour. (I see you edited your answer right when I posted this comment)
                          – marstran
                          Sep 6 at 10:24











                        • @marstran see another edit, I find this a very very weird
                          – Eugene
                          Sep 6 at 10:34






                        • 3




                          @AxelH & Eugene, I agree, this method is misnamed. This should be named something like assertEqualContentsOrdered. It would be useful for comparing a list and a set, in the case that you know that the set is ordered. (There is already assertEqualsNoOrder but it only takes arrays.)
                          – Stuart Marks
                          Sep 6 at 16:37







                        5




                        5




                        I find that a dangerous choice from junit to call assetEquals but not use Object.equals... this lead to "unexpected" behavior like this one.
                        – AxelH
                        Sep 6 at 10:22





                        I find that a dangerous choice from junit to call assetEquals but not use Object.equals... this lead to "unexpected" behavior like this one.
                        – AxelH
                        Sep 6 at 10:22













                        @AxelH indeed, I was really not expecting this
                        – Eugene
                        Sep 6 at 10:23




                        @AxelH indeed, I was really not expecting this
                        – Eugene
                        Sep 6 at 10:23












                        Junit throws an AssertionError here. It is testng which has this behaviour. (I see you edited your answer right when I posted this comment)
                        – marstran
                        Sep 6 at 10:24





                        Junit throws an AssertionError here. It is testng which has this behaviour. (I see you edited your answer right when I posted this comment)
                        – marstran
                        Sep 6 at 10:24













                        @marstran see another edit, I find this a very very weird
                        – Eugene
                        Sep 6 at 10:34




                        @marstran see another edit, I find this a very very weird
                        – Eugene
                        Sep 6 at 10:34




                        3




                        3




                        @AxelH & Eugene, I agree, this method is misnamed. This should be named something like assertEqualContentsOrdered. It would be useful for comparing a list and a set, in the case that you know that the set is ordered. (There is already assertEqualsNoOrder but it only takes arrays.)
                        – Stuart Marks
                        Sep 6 at 16:37




                        @AxelH & Eugene, I agree, this method is misnamed. This should be named something like assertEqualContentsOrdered. It would be useful for comparing a list and a set, in the case that you know that the set is ordered. (There is already assertEqualsNoOrder but it only takes arrays.)
                        – Stuart Marks
                        Sep 6 at 16:37










                        up vote
                        7
                        down vote













                        Testng calls through to a method implemented this way.



                         public static void assertEquals(Collection<?> actual, Collection<?> expected, String message) 


                        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





                        share|improve this answer






















                        • It's calling this overload: github.com/cbeust/testng/blob/master/src/main/java/org/testng/…
                          – marstran
                          Sep 6 at 10:27










                        • @marstran ouch, so the type of the reference rather than the object changes the behaviour.
                          – Peter Lawrey
                          Sep 6 at 10:30






                        • 1




                          Yep. The overload should have another name imho. Like assertSameElements or something.
                          – marstran
                          Sep 6 at 10:35










                        • @marstran or assertEquals(Object,Object) should check at runtime but even then it's really only good for List not Set
                          – Peter Lawrey
                          Sep 6 at 10:45







                        • 3




                          @AxelH This function is bad other reasons, but that fact that it considers null == null is perfectly consistent with the rest of the language.
                          – Todd Sewell
                          Sep 6 at 11:53














                        up vote
                        7
                        down vote













                        Testng calls through to a method implemented this way.



                         public static void assertEquals(Collection<?> actual, Collection<?> expected, String message) 


                        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





                        share|improve this answer






















                        • It's calling this overload: github.com/cbeust/testng/blob/master/src/main/java/org/testng/…
                          – marstran
                          Sep 6 at 10:27










                        • @marstran ouch, so the type of the reference rather than the object changes the behaviour.
                          – Peter Lawrey
                          Sep 6 at 10:30






                        • 1




                          Yep. The overload should have another name imho. Like assertSameElements or something.
                          – marstran
                          Sep 6 at 10:35










                        • @marstran or assertEquals(Object,Object) should check at runtime but even then it's really only good for List not Set
                          – Peter Lawrey
                          Sep 6 at 10:45







                        • 3




                          @AxelH This function is bad other reasons, but that fact that it considers null == null is perfectly consistent with the rest of the language.
                          – Todd Sewell
                          Sep 6 at 11:53












                        up vote
                        7
                        down vote










                        up vote
                        7
                        down vote









                        Testng calls through to a method implemented this way.



                         public static void assertEquals(Collection<?> actual, Collection<?> expected, String message) 


                        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





                        share|improve this answer














                        Testng calls through to a method implemented this way.



                         public static void assertEquals(Collection<?> actual, Collection<?> expected, String message) 


                        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






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Sep 6 at 10:58

























                        answered Sep 6 at 10:26









                        Peter Lawrey

                        429k54538912




                        429k54538912











                        • It's calling this overload: github.com/cbeust/testng/blob/master/src/main/java/org/testng/…
                          – marstran
                          Sep 6 at 10:27










                        • @marstran ouch, so the type of the reference rather than the object changes the behaviour.
                          – Peter Lawrey
                          Sep 6 at 10:30






                        • 1




                          Yep. The overload should have another name imho. Like assertSameElements or something.
                          – marstran
                          Sep 6 at 10:35










                        • @marstran or assertEquals(Object,Object) should check at runtime but even then it's really only good for List not Set
                          – Peter Lawrey
                          Sep 6 at 10:45







                        • 3




                          @AxelH This function is bad other reasons, but that fact that it considers null == null is perfectly consistent with the rest of the language.
                          – Todd Sewell
                          Sep 6 at 11:53
















                        • It's calling this overload: github.com/cbeust/testng/blob/master/src/main/java/org/testng/…
                          – marstran
                          Sep 6 at 10:27










                        • @marstran ouch, so the type of the reference rather than the object changes the behaviour.
                          – Peter Lawrey
                          Sep 6 at 10:30






                        • 1




                          Yep. The overload should have another name imho. Like assertSameElements or something.
                          – marstran
                          Sep 6 at 10:35










                        • @marstran or assertEquals(Object,Object) should check at runtime but even then it's really only good for List not Set
                          – Peter Lawrey
                          Sep 6 at 10:45







                        • 3




                          @AxelH This function is bad other reasons, but that fact that it considers null == null is perfectly consistent with the rest of the language.
                          – Todd Sewell
                          Sep 6 at 11:53















                        It's calling this overload: github.com/cbeust/testng/blob/master/src/main/java/org/testng/…
                        – marstran
                        Sep 6 at 10:27




                        It's calling this overload: github.com/cbeust/testng/blob/master/src/main/java/org/testng/…
                        – marstran
                        Sep 6 at 10:27












                        @marstran ouch, so the type of the reference rather than the object changes the behaviour.
                        – Peter Lawrey
                        Sep 6 at 10:30




                        @marstran ouch, so the type of the reference rather than the object changes the behaviour.
                        – Peter Lawrey
                        Sep 6 at 10:30




                        1




                        1




                        Yep. The overload should have another name imho. Like assertSameElements or something.
                        – marstran
                        Sep 6 at 10:35




                        Yep. The overload should have another name imho. Like assertSameElements or something.
                        – marstran
                        Sep 6 at 10:35












                        @marstran or assertEquals(Object,Object) should check at runtime but even then it's really only good for List not Set
                        – Peter Lawrey
                        Sep 6 at 10:45





                        @marstran or assertEquals(Object,Object) should check at runtime but even then it's really only good for List not Set
                        – Peter Lawrey
                        Sep 6 at 10:45





                        3




                        3




                        @AxelH This function is bad other reasons, but that fact that it considers null == null is perfectly consistent with the rest of the language.
                        – Todd Sewell
                        Sep 6 at 11:53




                        @AxelH This function is bad other reasons, but that fact that it considers null == null is perfectly consistent with the rest of the language.
                        – Todd Sewell
                        Sep 6 at 11:53










                        up vote
                        5
                        down vote













                        Because for collection only content is compared, not collection type.



                        Rationale behind it is that often some subclass of collection is returned from tested method and is irrelevant what exactly subclass is used.






                        share|improve this answer
























                          up vote
                          5
                          down vote













                          Because for collection only content is compared, not collection type.



                          Rationale behind it is that often some subclass of collection is returned from tested method and is irrelevant what exactly subclass is used.






                          share|improve this answer






















                            up vote
                            5
                            down vote










                            up vote
                            5
                            down vote









                            Because for collection only content is compared, not collection type.



                            Rationale behind it is that often some subclass of collection is returned from tested method and is irrelevant what exactly subclass is used.






                            share|improve this answer












                            Because for collection only content is compared, not collection type.



                            Rationale behind it is that often some subclass of collection is returned from tested method and is irrelevant what exactly subclass is used.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Sep 6 at 10:19









                            talex

                            6,8511544




                            6,8511544




















                                up vote
                                2
                                down vote













                                When I run below code the condition is false.



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



                                Hence for assertEquals, it is true that it only checks elements and its order for equality. But for equals it is false.






                                share|improve this answer
























                                  up vote
                                  2
                                  down vote













                                  When I run below code the condition is false.



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



                                  Hence for assertEquals, it is true that it only checks elements and its order for equality. But for equals it is false.






                                  share|improve this answer






















                                    up vote
                                    2
                                    down vote










                                    up vote
                                    2
                                    down vote









                                    When I run below code the condition is false.



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



                                    Hence for assertEquals, it is true that it only checks elements and its order for equality. But for equals it is false.






                                    share|improve this answer












                                    When I run below code the condition is false.



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



                                    Hence for assertEquals, it is true that it only checks elements and its order for equality. But for equals it is false.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered Sep 6 at 10:24









                                    Raj

                                    28912




                                    28912



























                                         

                                        draft saved


                                        draft discarded















































                                         


                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function ()
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52201814%2fwhy-are-empty-collections-of-different-type-equal%23new-answer', 'question_page');

                                        );

                                        Post as a guest













































































                                        Comments

                                        Popular posts from this blog

                                        Long meetings (6-7 hours a day): Being “babysat” by supervisor

                                        Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

                                        Confectionery