# AssertEquals 2 Lists ignore order

That should be really simple question I believe. But somehow I can't find answer in Google.

Assume that I have 2 Lists of Strings. First contains "String A" and "String B", second one contains "String B" and "String A" (notice difference in order). I want to test them with JUnit to check whether they contains exactly the same Strings.

Is there any assert that checks equality of Strings that ignore order? For given example org.junit.Assert.assertEquals throws AssertionError

``````java.lang.AssertionError: expected:<[String A, String B]> but was:<[String B, String A]>
``````

Work around is to sort Lists firstly and then pass them to assertion. But I want my code to be as simple and clean as possible.

I use Hamcrest 1.3, JUnit 4.11, Mockito 1.9.5.

• `list1.removeAll(list2)` should leave `list1` empty. I guess you can build on this to get what you want. – RainMaker Apr 2 '14 at 9:45
• `containsAll` and `removeAll` are `O(n²)` for lists while sorting them and test for equality is `O(nlogn)`. `Collections.sort(list1); Collections.sort(list2); assertTrue(list1.equals(list2));` is also clean. – Alexis C. Apr 2 '14 at 9:46
• possible duplicate of Hamcrest compare collections – Joe Apr 5 '14 at 8:28
• @SudoRahul - What if you do not want to modify a list by removing all ? – Erran Morad Dec 13 '17 at 7:23
• @BoratSagdiyev - Since that was not a constraint from the OP, I suggested that. But if that is a constraint, then the accepted answer for this question solves the problem at hand. – RainMaker Dec 14 '17 at 6:34

As you mention that you use Hamcrest, I would pick one of the collection Matchers

``````import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
import static org.junit.Assert.assertThat;

public class CompareListTest {

@Test
public void compareList() {
List<String> expected = Arrays.asList("String A", "String B");
List<String> actual = Arrays.asList("String B", "String A");

assertThat("List equality without order",
actual, containsInAnyOrder(expected.toArray()));
}

}
``````

You can use List.containsAll with JUnit's assertTrue to check that the first list contains every element from the second one, and vice versa.

``````assertTrue(first.size() == second.size() &&
first.containsAll(second) && second.containsAll(first));
``````
• @kukis It depends, do you want to check for duplicates? – robertoia Apr 2 '14 at 10:24
• Yes, of course. 2 given Lists must be exactly the same just ignoring order. – kukis Apr 2 '14 at 10:26
• @kukis Check ZouZou's comment on your question then. – robertoia Apr 2 '14 at 10:28
• ..might include `assertEquals(first.size(), second.size())` ..then it should work as expected – definitely undefinable May 24 '16 at 15:16
• This doesn't work with duplicates in the list. Here's an example to demonstrate: `List<String> list1 = Arrays.asList("a", "a", "b");` `List<String> list2 = Arrays.asList("a", "b", "b");` `assertEquals(list1.size(), list2.size());` `assertTrue(list1.containsAll(list2) && list2.containsAll(list1));` In this example, both assertions fail to detect that the lists are actually different. @AlexWorden mentions Apache Commons Collections' CollectionUtils.isEqualCollection() which, for this example, correctly detects that the collections are not equal. – desilvai Jun 30 '16 at 16:53

Here's a solution that avoids quadratic complexity (iterating over the lists multiple times). This uses the Apache Commons CollectionUtils class to create a Map of each item to a frequency count itself in the list. It then simply compares the two Maps.

``````Assert.assertEquals("Verify same metrics series",
CollectionUtils.getCardinalityMap(expectedSeriesList),
CollectionUtils.getCardinalityMap(actualSeriesList));
``````

I also just spotted CollectionUtils.isEqualCollection that claims to do exactly what is being requested here...

https://commons.apache.org/proper/commons-collections/apidocs/index.html?org/apache/commons/collections4/CollectionUtils.html

With AssertJ, `containsExactlyInAnyOrder()` or `containsExactlyInAnyOrderElementsOf()` is what you need :

``````import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.List;

public class CompareListTest {

@Test
public void compareListWithTwoVariables() {
List<String> expected = Arrays.asList("String A", "String B");
List<String> actual = Arrays.asList("String B", "String A");
Assertions.assertThat(actual)
.containsExactlyInAnyOrderElementsOf(expected);
}

@Test
public void compareListWithInlineExpectedValues() {
List<String> actual = Arrays.asList("String B", "String A");
Assertions.assertThat(actual)
.containsExactlyInAnyOrder("String A", "String B");
}
}
``````
``````    Collections.sort(excepted);
Collections.sort(actual);
assertEquals(excepted,actual);
``````

Im late to the party but here's my solution using Junit only. Any thoughts are welcome.

``````List<String> actual = new ArrayList<>();

List<String> expected = new ArrayList<>();

//Step 1: assert for size
assertEquals(actual.size(), expected.size());

//Step 2: Iterate
for(String e: expected){
assertTrue(actual.contains(e));
actual.remove(e);
}
``````

Note that solution by Roberto Izquierdo has quadratic complexity in general. Solution on HashSets always has linear complexity:

``````assertTrue(first.size() == second.size() &&
new HashSet(first).equals(new HashSet(second)));
``````
• That approach won't work. If first is ("String A") and second is ("String A", "String A") they are not the same lists. – Alexis C. Apr 2 '14 at 9:49
• You can't check the size. If first is `("s1", "s2", "s3" ,"s1")` and second is `("s2", "s1", "s3" ,"s2");` they are not the same list. – Alexis C. Apr 2 '14 at 9:54
• @ZouZou the accepted solution has the same problem. You suggested the only really correct solution. If you make an answer I will upvote it. – leventov Apr 2 '14 at 10:01
• @ZouZou They are not the same list, but they contain exactly the same Strings. OP, clarify?. Also, make it an answer and I will upvote too :) didn't think of that. – robertoia Apr 2 '14 at 10:09
• This is still not correct for all cases ("A", "A", "B") will compare as equal to ("A", "B", "B") – Tim B Feb 7 '17 at 16:58

For a quick fix I would check both ways:

``````assertTrue(first.containsAll(second));
assertTrue(second.containsAll(first));
``````

And trying with a situation where the number of the same elements is different (e.g. 1, 1, 2 and 1, 2, 2) I didn't get false positives.

• Your code still fails. See this example - @Test public void test1() { List<String> list1 = Arrays.asList("a", "a", "b"); List<String> list2 = Arrays.asList("a", "b", "b"); Assert.assertTrue(list1.containsAll(list2)); Assert.assertTrue(list2.containsAll(list1)); } – Erran Morad Dec 13 '17 at 7:20

You can use ListAssert that comes in junit-addons jar.

``````ListAssert.assertEquals(yourList, Arrays.asList(3, 4, 5));
``````

Looks like the other answers either reference 3rd party utils, are incorrect, or are inefficient.

Here's a O(N) vanilla solution in Java 8.

``````public static void assertContainsSame(Collection<?> expected, Collection<?> actual)
{
assert expected.size() == actual.size();

Map<Object, Long> counts = expected.stream()
.collect(Collectors.groupingBy(
item -> item,
Collectors.counting()));

for (Object item : actual)
assert counts.merge(item, -1L, Long::sum) != -1L;
}
``````
{"ft_lang_label":"__label__en","ft_lang_prob":0.84967405,"math_prob":0.59141666,"size":1095,"snap":"2021-21-2021-25","text_gpt3_token_len":279,"char_repetition_ratio":0.117323555,"word_repetition_ratio":0.0,"special_character_ratio":0.25114155,"punctuation_ratio":0.1724138,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9574798,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2021-05-17T01:45:21Z\",\"WARC-Record-ID\":\"<urn:uuid:4730fdb8-65e5-4516-a9ac-aebc4aec32f2>\",\"Content-Length\":\"265365\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:72b515bf-60cf-4dbc-9ec3-fbf4cad1abde>\",\"WARC-Concurrent-To\":\"<urn:uuid:788ccdfc-92d6-41a3-a71b-98043130ea25>\",\"WARC-IP-Address\":\"151.101.129.69\",\"WARC-Target-URI\":\"https://stackoverflow.com/questions/22807328/assertequals-2-lists-ignore-order/22840486\",\"WARC-Payload-Digest\":\"sha1:RGKWJRV745MALFGTWWJSP33RTVFYYCBW\",\"WARC-Block-Digest\":\"sha1:2FUEDDP42ITFWMX566ZITIP6ZNUDW3W2\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2021/CC-MAIN-2021-21/CC-MAIN-2021-21_segments_1620243991921.61_warc_CC-MAIN-20210516232554-20210517022554-00240.warc.gz\"}"}