我有两个E类型列表List list1,List list2。 E对象是一个POJO类,包含一行以下数据。两个列表都包含相同的数据。例如,在最后一列,如果我将false更改为true,则无法检测到。
| 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 |
我想写一个函数,这样如果数据是那两个列表不同,那么就可以检测到它。以下是我的代码,但似乎总是给出“假”,两个列表中的数据是相同还是不同。
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;
}
答案 0 :(得分:5)
更好的方法(假设列表不包含重复值)是将一个列表的所有元素存储在HashSet
中,然后检查HashSet
是否包含所有元素另一个列表的元素和它们的大小是相同的。
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);
}
这是O(n+m)
解决方案,而使用List.containsAll()
需要迭代其他列表的所有元素以检查是否存在,因此它将是O(n*m)
答案 1 :(得分:1)
基本上,如果大小相等,您可以迭代两个列表,当您在expectedStatuses
中找不到actualStatuses
中找不到的第一个状态时,您可以返回false,因为列表不是等于了。
但是,如果列表变大,您可能会遇到性能问题,因为这基本上是O(n 2 )方法。在这种情况下,您可以先将所有预期的状态放入一个集合中,然后删除实际的状态。如果最后该集合不为空,则列表不相等,您甚至不知道缺少哪些状态。如果您只需要检查是否相等,只需检查该集是否包含第二个列表的元素。在最坏的情况下,两者都是O(n)。
注意List.containsAll()
与上面描述的基本相同,即遍历集合参数,并且每个元素在其自己的列表中查找(调用contains(e)
)并且在找不到的第一个元素上返回false
编辑:
如果您的元素已正确实施List.containsAll()
和hashCode()
,则使用集合与equals()
同样简单:
new HashSet<Status>( expectedStatuses ).containsAll( actualStatuses );
答案 2 :(得分:0)
怎么样:
private boolean compareLists(List<Status> actualStatuses, List<Status> expectedStatuses) {
boolean listsHaveSameSize = actualStatuses.size() == expectedStatuses.size();
return listsHaveSameSize ? actualStatuses.containsAll(expectedStatuses)
: false;
}
答案 3 :(得分:0)
public <T> boolean equalsIgnoreOrder(List<T> list1, List<T> list2) {
if (list1.size() != list2.size()) {
return false;
}
Map<T, Integer> map1 = createCountMap(list1);
Map<T, Integer> map2 = createCountMap(list2);
return map1.equals(map2);
}
/**
* Note that T must have a proper hashCode() and equals() for this to work
*/
private <T> Map<T, Integer> createCountMap(List<T> list) {
Map<T, Integer> map = new HashMap<T, Integer>();
for (T value : list) {
Integer prevCount = map.get(value);
map.put(value, prevCount == null ? 1 : prevCount + 1);
}
return map;
}