Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assert List<List<String>> contains List<String> with no order

I have a List<List<String>> with sample data like:

("T1#R1", "T1#R1", "T1#R3", "T1#R4")
("T1#R1", "T1#R1", "T1#R3", "T1#R5")
("T1#R1", "T1#R1", "T1#R6", "T1#R4")
("T1#R1", "T1#R1", "T1#R6", "T1#R5")

And I need to assert, that a List<String> is present in the above sample, but without taking order into consideration.

For example, the following list ("T1#R1", "T1#R1", "T1#R4", "T1#R3") should be considered as present in the List<List<String>>, as it would contain the same items as the 1st list, but in different order.

On the other hand, ("T1#R1", "T1#R3", "T1#R4", "T1#R3") shouldn't be considered as present in the list, as it has the same items, but with a different count.

I know I could do this programmatically, but was wandering if there could be a Matcher for example that could help.

I've seen assertions like:

assertThat(myList, containsInAnyOrder(anotherList.toArray())

But that would just compare one list with another, and not a list inside a List of Lists.

PS: I'm using Java6, hamcrest-core-1.3, testng-5.14.1

like image 837
Manuel S. Avatar asked Oct 18 '25 14:10

Manuel S.


1 Answers

I don't know of any matcher that can do what you want, so I'm afraid you'll have to program it.

I would simply sort the target list and then I'd iterate the sublists until a match is found:

List<String> target = new ArrayList<>(anotherList);
target.sort();

boolean result = myList.stream()
    .anyMatch(sublist -> equalsInAnyOrder(sublist, target));

Where method equalsInAnyOrder would be as follows:

public <T> boolean equalsInAnyOrder(List<T> sublist, List<T> target) {

    List<String> copy = new ArrayList<>(sublist);
    copy.sort();

    return copy.equals(target);
}

This sorts each sublist and compares it with the target sorted list, so it's not performance-wise, but at least it's simple and succint code.


EDIT as per OP's need to target Java 6:

The logic is exactly the same as in the Java 8 version. First sort the target list and then compare each sublist until a match is found:

List<String> target = new ArrayList<>(anotherList);
Collections.sort(target);

The stream() with anyMatch has now become a while loop:

boolean match = false;
Iterator<List<String>> it = myList.iterator();
while (it.hasNext() && !match) {
    List<String> sublist = it.next();
    match = equalsInAnyOrder(sublist, target);
}

And now method equalsInAnyOrder looks like this:

public <T> boolean equalsInAnyOrder(List<T> sublist, List<T> target) {

    List<String> copy = new ArrayList<>(sublist);
    Collections.sort(copy);

    return copy.equals(target);
}
like image 116
fps Avatar answered Oct 21 '25 05:10

fps



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!