簡體   English   中英

比較兩個清單 <E> 不管順序

[英]Compare two List<E> regardless of order

我有兩個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                |

我想編寫一個函數,以便如果數據是這兩個列表是不同的然后可以被檢測到。 以下是我的代碼,但無論兩個列表中的數據相同還是不同,它似乎總是給出“ 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;
}

一種更好的方法(假設列表不包含重復的值)是將一個列表的所有元素存儲在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)

基本上,如果大小相等,你可以只遍歷兩個列表,當你發現在第一狀態expectedStatuses未在發現actualStatuses因為名單是不相等了,那么你可以返回false。

但是,如果列表變大,則可能會遇到性能問題,因為這基本上是O(n 2 )方法。 在這種情況下,您可以先將所有預期狀態放入一組,然后再刪除實際狀態。 如果最后該集合不為空,則列表不相等,您甚至會知道缺少哪些狀態。 如果只需要檢查是否相等,則只需檢查集合是否包含第二個列表的元素即可。 在最壞的情況下,兩者均為O(n)。

請注意, List.containsAll()操作與上述基本相同,即遍歷collection參數,並且每個元素都在其自己的列表中查找(調用contains(e) ),在第一個未找到的元素上返回false。

編輯:

如果您的元素具有正確實現的hashCode()equals() ,則使用set就像List.containsAll()一樣簡單:

new HashSet<Status>( expectedStatuses ).containsAll( actualStatuses );

關於什么:

private boolean compareLists(List<Status> actualStatuses, List<Status> expectedStatuses) {
    boolean listsHaveSameSize = actualStatuses.size() == expectedStatuses.size();

    return listsHaveSameSize ? actualStatuses.containsAll(expectedStatuses)
                             : false;
}
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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM