簡體   English   中英

如何檢查兩個ArrayList是否不同,我不在乎改變了什么

[英]How can I check if two ArrayList differ, I don't care what's changed

如何檢查兩個ArrayLists是否彼此不同? 我不在乎有什么不同,我只是想知道他們是不是一樣。

我每分鍾從數據庫中獲取分數列表,並且只有當我獲取的分數列表與我在一分鍾前獲取的分數列表不同時,我才想將其發送給客戶端。

現在,ArrayList的值實際上是我創建的一個類(包含name,lvl,rank,score)。

我需要在它上面實現equals()嗎?

關於“同一性”的定義

正如Joachim所指出的,對於大多數應用程序, List.equals(Object o)定義有效:

將指定對象與此列表進行比較以獲得相等性。 當且僅當指定的對象也是列表時,返回true ,兩個列表具有相同的大小,並且兩個列表中的所有對應元素對都相等。 (如果(e1==null ? e2==null : e1.equals(e2))則兩個元素e1e2相等。)換句話說,如果兩個列表包含相同順序的相同元素,則它們被定義為相等。 此定義確保equals方法在List接口的不同實現中正常工作。

但是,根據您使用它的方式,這可能無法按預期工作。 例如,如果你有一個List<int[]> ,它就不能正常工作,因為數組從Object繼承equals ,它將相等性定義為引用標識。

    List<int[]> list1 = Arrays.asList(new int[] { 1, 2, 3 });
    List<int[]> list2 = Arrays.asList(new int[] { 1, 2, 3 });
    System.out.println(list1.equals(list2)); // prints "false"

此外,具有不同類型參數的兩個列表可以equals

    List<Number> list1 = new ArrayList<Number>();
    List<String> list2 = new ArrayList<String>();
    System.out.println(list1.equals(list2)); // prints "true"

您還提到該列表必須包含具有相同類型的元素。 這是另一個示例,其中元素的類型不同,但它們equals

    List<Object> list1 = new ArrayList<Object>();
    List<Object> list2 = new ArrayList<Object>();
    list1.add(new ArrayList<Integer>());
    list2.add(new LinkedList<String>());
    System.out.println(list1.equals(list2)); // prints "true"

因此,除非您明確定義平等對您意味着什么,否則問題可能會有非常不同的答案。 但是,對於大多數實際用途, List.equals應該足夠了。


實施equals

更新后的信息表明List.equals可以正常工作, 前提是元素正確實現equals (因為List<E>.equals根據上面的API文檔調用非null E.equals上的E.equals )。

所以在這種情況下,如果我們有一個List<Player> ,那么Player必須@Override equals(Object o)才能返回true如果是o instanceof Player ,那么在相關字段中,它們都是equals (對於引用類型)或== (對於基元)。

當然,當@Override equals ,你也應該@Override int hashCode() 幾乎不可接受的最低要求是return 42; ; 稍微好一點就是return name.hashCode(); ; 最好是使用涉及您定義的所有字段equals的公式。 一個好的IDE可以自動為你生成equals/hashCode方法。

也可以看看

  • 有效的Java第二版
    • 第8項:在超越平等時遵守總合同
    • 第9項:覆蓋equals時始終覆蓋hashcode

API鏈接

相關問題

equals/hashCode組合中:

equals vs ==

使用equals() 只要列表中的元素正確實現equals() ,它就會返回正確的值。

除非您想忽略值的順序,否則您應該將值轉儲到兩個Set對象中,並使用equals()進行比較。

這是一個簡單的方法,可以檢查2個數組列表是否包含相同的值,無論它們的順序如何。

 //the name of the method explains it well...
    public boolean isTwoArrayListsWithSameValues(ArrayList<Object> list1, ArrayList<Object> list2)
    {
        //null checking
        if(list1==null && list2==null)
            return true;
        if((list1 == null && list2 != null) || (list1 != null && list2 == null))
            return false;

        if(list1.size()!=list2.size())
            return false;
        for(Object itemList1: list1)
        {
            if(!list2.contains(itemList1))
                return false;
        }

        return true;
    }

正如@Joachim Sauer在他的回答中提到的,如果列表相等且其內容正確地實現等於,則equals應該有效。 但是,如果項目不在同一個“訂單”中,它不應該工作,因為它不使用包含檢查。 從這個意義上講,它檢查@jarnbjo所提到的“嚴格”平等

        //From android's Arraylist implementation
        Iterator<?> it = that.iterator();
        for (int i = 0; i < s; i++) {
            Object eThis = a[i];
            Object eThat = it.next();
            if (eThis == null ? eThat != null : !eThis.equals(eThat)) {
                return false;
            }
        }

但是,我想要一些不同的行為,我不關心訂單或類似的東西。 我想要的只是確保兩個不包含相同的項目。 我的解決方案

    //first check that both are not null and are of same length. (not shown here)
    //if both match, pull out the big guns as below
    ...
    List<Object> comparedList = new ArrayList<>(listOne);
    comparedList.removeAll(listTwo);
    if(comparedList.size() != 0) //there are differences between the two

這樣性能較差,因為它循環兩次,首先在removeAll ,然后在contains中由removeAll調用。

我的名單保證很短,所以我不介意打擊。

你可以將它們轉換為字符串然后進行比較

list1.toString().equals(list2.toString())

您還可以查看Arraylist,如下所示:

public  boolean equalLists(List<String> one, List<String> two){     
if (one == null && two == null){
    return true;
}

if((one == null && two != null) 
  || one != null && two == null
  || one.size() != two.size()){
    return false;
}

//to avoid messing the order of the lists we will use a copy
//as noted in comments by A. R. S.
one = new ArrayList<String>(one); 
two = new ArrayList<String>(two);   

Collections.sort(one);
Collections.sort(two);      
return one.equals(two);
}

感謝@Jacob

暫無
暫無

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

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