簡體   English   中英

如何比較兩個數組列表與自定義比較器的相等性?

[英]How can I compare two array lists for equality with a custom comparator?

具體來說,我有兩個清單:

List<SystemUserWithNameAndId> list1;
List<SystemUserWithNameAndId> list2;

我想檢查它們是否包含相同的系統用戶,並且訂購不是問題。 我嘗試先使用比較器對它們進行排序,然后使用列表的equals()方法檢查它們是否相等。 但我不想覆蓋SystemUserWithNameAndId的equals方法,我想知道我是否可以使用我為排序創建的比較器或類似的比較器來檢查相等性,而不會在排序后顯式迭代列表。

Comparator<SystemUserWithNameAndId> systemUserComparator = new Comparator<SystemUserWithNameAndId>()
    {

        @Override
        public int compare(SystemUserWithNameAndId systemUser1, SystemUserWithNameAndId systemUser2)
        {
            final int systemUserId1 = systemUser1.getSystemUserId();
            final int systemUserId2 = systemUser2.getSystemUserId();

            return systemUserId1 == systemUserId2 
                    ? 0
                    : systemUserId1 - systemUserId2;
        }
    };

    Collections.sort(systemUsers1, systemUserComparator);
    Collections.sort(systemUsers2, systemUserComparator);

    return systemUsers1.equals(systemUsers2);

理想情況下,我希望能夠說,

CollectionUtils.isEqualCollections(systemUsers1, systemUsers2, someCustomComparator);

只需實現迭代的方法,並在每次需要時重用它:

public static <T> boolean areEqualIgnoringOrder(List<T> list1, List<T> list2, Comparator<? super T> comparator) {

    // if not the same size, lists are not equal
    if (list1.size() != list2.size()) {
        return false;
    }

    // create sorted copies to avoid modifying the original lists
    List<T> copy1 = new ArrayList<>(list1);
    List<T> copy2 = new ArrayList<>(list2);

    Collections.sort(copy1, comparator);
    Collections.sort(copy2, comparator);

    // iterate through the elements and compare them one by one using
    // the provided comparator.
    Iterator<T> it1 = copy1.iterator();
    Iterator<T> it2 = copy2.iterator();
    while (it1.hasNext()) {
        T t1 = it1.next();
        T t2 = it2.next();
        if (comparator.compare(t1, t2) != 0) {
            // as soon as a difference is found, stop looping
            return false;
        }
    }
    return true;
}

這是解決問題的Java 8方法。 首先確保列表長度相等:

List<SystemUserWithNameAndId> list1 = ... ;
List<SystemUserWithNameAndId> list2 = ... ;

if (list1.size() != list2.size()) {
    return false;
}

現在使用新的比較器實用程序構建Comparator。 我們的想法是,大多數比較器不是為比較器編寫自定義邏輯,而是通過從兩個對象中提取密鑰來比較兩個對象,然后比較密鑰。 這就是它的作用。

Comparator<SystemUserWithNameAndId> comp =
    Comparator.comparingInt(SystemUserWithNameAndId::getSystemUserId);

對列表進行排序。 當然,如果您不希望函數具有對其輸入進行排序的副作用,您可能希望在排序之前制作副本。 如果你的輸入列表不是隨機訪問(誰現在使用LinkedList ?),你可能還想將它們復制到ArrayList以方便隨機訪問。

list1.sort(comp);
list2.sort(comp);

在列表的索引上運行流,在每對上調用比較器。 如果元素根據此比較器等於,則比較器返回0。 如果對於所有元素對都是如此,則列表是相等的。

return IntStream.range(0, list1.size())
    .allMatch(i -> comp.compare(list1.get(i), list2.get(i)) == 0);

暫無
暫無

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

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