You can sort the lists easily as follows:
List<String> WORD_OF_ADDRESS_sorted gatekeeperPage.getWords(ADDRESS)
.stream().sorted().toList();
List<String> WORD_OF_CONTACT_ADDRESS_sorted = gatekeeperPage.getWords(CONTACT_ADDRESS)
.stream().sorted().toList();
Then you can compare them.
However, if you just want to see if they are equal based on contents, sorting is not necessary to test for content equality. Update a map with a running count each time the item occurs is more efficient. Add 1
for one list and subtract 1
for the other. Map.merge
is useful because it permits one to replace a 0
value with null
which then removes the entry. So if you end up with an empty map, the lists must be equal based on contents.
public static <T> boolean areEqual(List<T> list1, List<T> list2) {
Map<T, Integer> map = new HashMap<>();
if (list1.size() != list2.size()) {
return false;
}
for (int i = 0; i < list1.size(); i++) {
map.merge(list1.get(i), -1,
(k, v) -> v + 1 == 0 ? null : v + 1);
map.merge(list2.get(i), 1,
(k, v) -> v - 1 == 0 ? null : v - 1);
}
return map.isEmpty();
}
I have not extensively tested this but with the all tests using lists of random integers, where only one is copied shuffled tested as equal. Randomly salting the lists with different values tested as false.
Since immutable lists are not altered, they can be passed directly to the method.
Caveat: Since Integers have a maximum value and minimum value, extremely large lists have the potential to fail if those limits are reached. Counting of Long
or BigInteger
would mitigate this problem but also decrease its performance.