I have two E type lists List list1, List list2. The E object is a POJO class that contains a row of the following data. Both of the lists contain same data. For example at the last column if I change a false to true it cannot detect.
| statusId | statusName | statusState | isRequire |
| 3 | Approved | APPROVED | false |
| 201 | Attributed | REJECTED | true |
| 202 | Denied | REJECTED | false |
| 204 | Fraud | REJECTED | false |
| 205 | Insufficient | REJECTED | false |
| 206 | Invalid | REJECTED | false |
| 207 | Cancelled | REJECTED | false |
| 208 | Cannot traced | REJECTED | false |
| 209 | Transaction online | REJECTED | false |
| 210 | Voucher | REJECTED | false |
| 211 | does not meet req | REJECTED | false |
I want to write a function so that if data is those two lists are different then that can be detectected. Following is my code but seems like it always give 'false' whether data is same or different in both lists.
private boolean compareLists(List<Status> actualStatuses, List<Status> expectedStatuses) {
boolean indicator = false;
if (actualStatuses!= null && expectedStatuses!=null && actualStatuses.size() == expectedStatuses.size()){
for (Status expectedStatusData : expectedStatuses){
for(Status actualStatusData : actualStatuses){
if(actualStatusData.getStatusId() == expectedStatusData.getStatusId()
&& actualStatusData.getStatusName().equals(expectedStatusData.getStatusName())
&& actualStatusData.getStatusState().equals(expectedStatusData.getStatusState())
&& actualStatusData.isEnable() == expectedStatusData.isEnable()
&& actualClaimStatusData.isRequire() == expectedStatusData.isRequire()){
indicator = true;
break;
}
else indicator = false;
}
}
if (indicator)
return true;
}
else
return false;
return indicator;
}
A better way of doing this (assuming the list doesn't contain repeated values) is to store all the elements of one list in a HashSet and then check if the HashSet contains all of the elements of the other list and that their sizes are the same.
private <E> boolean listsHaveSameElements(final List<E> l1, final List<E> l2) {
final Set<E> set = new HashSet<>(l1);
return l1.size() == l2.size() && set.containsAll(l2);
}
This is an O(n+m) solution while using List.containsAll() would need to iterate all the elements of the other list to check for existence so it would be O(n*m)
Basically, if the sizes are equal, you could just iterate over both lists and when you find the first status in expectedStatuses that is not found in actualStatuses you can return false since the lists are not equal anymore.
However, if the lists get bigger you might run into performance issues since that's basically a O(n2) approach. In that case you could first put all expected statuses into a set and remove the actual ones afterwards. If at the end the set is not empty the lists are not equal and you'd even know which statuses are missing. If you only need to check for equality just check whether the set contains the elements of the second list. Both would be O(n) in the worst case.
Note that List.containsAll() does basically the same as described above, i.e. iterates over the collection parameter and for each element looks in its own list (calling contains(e)) and on the first element not found returns false.
Edit:
Using a set would be equally simple as List.containsAll(), provided your elements have their hashCode() and equals() implemented properly:
new HashSet<Status>( expectedStatuses ).containsAll( actualStatuses );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With