Soru İki ArrayList'in farklı olup olmadığını nasıl kontrol edebilirim, neyin değiştiğini umursamıyorum


İki ArrayLists'in birbirinden farklı olup olmadığını nasıl kontrol edebilirim? Farkın ne olduğu umrumda değil, sadece aynı olmadıklarını bilmek istiyorum.

Her dakika bir veri tabanından puan listesi alıyorum ve yalnızca aldığım puanlar listesi, bir dakika önce getirdiğimden farklıysa, müşteriye göndermek istiyorum.

Şimdi ArrayList'in değeri aslında oluşturduğum bir sınıftır (ad, lvl, rütbe, skor içerir).

Uygulamak zorunda mıyım equals() üstünde?


34
2018-06-07 13:41


Menşei


"Aynı" nedir? Liste mi [1, 2, 3] aynı [1.0, 2.0, 3.0]? Ne dersin [3, 2, 1]? Veya ["one", "two", "three"]? Neyin aynı / fark olarak sayıldığını tanımlamak istemezseniz, sadece şunu söyleyebiliriz == ve !=. En azından bu bir İki nesnenin aynı olup olmadığının tanımı. - polygenelubricants
@polygenelubricants: Aksi belirtilmediği sürece "aynı olan" anlamına gelir equals() Java'da. Burada bunun neden sorgulanması gerektiğini anlamıyorum. - Joachim Sauer
@Joachim: Eğer OP eşitliği tanımlamak demektir equalsdaha sonra OP zaten cevabı biliyordu ve soruyu ilk etapta sormadı, değil mi? (yani Q: Nasıl kontrol edebilirim list1 olduğu equals için list2? A: Kullanın list1.equals(list2)) - polygenelubricants
Aynı tür ve aynı sipariş ile aynı değerleri gerektirir - ufk
o zaman eşittir (). Değerlerinizin, bir eşitlik işlevini tanımlayan bir sınıf olduğundan ve iyi olmanız gerektiğinden emin olun. - Lizzan


Cevaplar:


İşte 2 Array Listelerinin, siparişlerine bakılmaksızın aynı değerleri içerip içermediğini kontrol eden basit bir yöntem.

 //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;
    }

6
2018-01-22 07:41





"Aynılığın" tanımı üzerine

Joachim'in belirttiği gibi, çoğu uygulama için List.equals(Object o) tanımı çalışır:

Belirtilen nesneyi eşitlik için bu listede karşılaştırır. İade true ve eğer sadece belirtilen nesne aynı zamanda bir liste ise, her iki liste de aynı büyüklüğe sahiptir ve iki listedeki tüm karşılık gelen eleman çiftleri eşittir. (İki eleman e1 ve e2 eşitse (e1==null ? e2==null : e1.equals(e2)).) Diğer bir deyişle, aynı sırayla aynı unsurları içeriyorsa iki liste eşit olacak şekilde tanımlanır. Bu tanım, equals yöntem, farklı uygulamalarda düzgün çalışır. List arayüz.

Bunu nasıl kullandığınıza bağlı olarak, bu beklendiği gibi çalışmayabilir. Eğer bir List<int[]>Örneğin, oldukça işe yaramıyor çünkü diziler miras kalıyor equals itibaren Object eşitliği referans kimliği olarak tanımlar.

    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"

Ayrıca, farklı tip parametresi olan iki liste de olabilir. equals:

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

Ayrıca listenin aynı türdeki öğeleri içermesi gerektiğini de belirttiniz. Burada öğelerin aynı türde olmadığı başka bir örnek var. 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"

Yani, eşitliğin sizin için ne anlama geldiğini açıkça belirlemedikçe, soru çok farklı cevaplara sahip olabilir. En pratik amaçlar için olsa da, List.equals yeterli olmalıdır.


Uygulamada equals

Güncelleme sonrası bilgiler List.equals işi iyi yapacak sağlanan elemanlar uygulamak equals düzgün çünkü List<E>.equals çağırır E.equals olmayannullYukarıdaki API belgelerine göre seçimler).

Yani bu durumda, eğer varsa, bir List<Player>, sonra Player şart @Override equals(Object o) geri vermek true Eğer o instanceof Player ve ilgili alanlarda, hepsi equals (referans türleri için) veya == (ilkel maddeler için).

Tabi ki, ne zaman @Override equalssen de yapmalısın @Override int hashCode(). Kabul edilebilir minimum, return 42;; biraz daha iyi return name.hashCode();; En iyi tanımladığınız tüm alanları içeren bir formül kullanmaktır equals. İyi bir IDE otomatik olarak üretebilir equals/hashCode sizin için yöntemler.

Ayrıca bakınız

  • Etkili Java 2. Sürüm
    • Madde 8: Eşitlik yaparken, genel sözleşmeye uyun
    • Öğe 9: Eşitlemeyi geçersiz kıldığınızda her zaman hash kodu geçersiz kıl

API bağlantıları

İlgili sorular

üzerinde equals/hashCode kombo:

üzerinde equals vs ==:


78
2018-06-07 14:05





kullanım equals(). Listelerdeki elemanlar uygulandığı sürece equals() doğru olarak doğru değerleri döndürecektir.

Değerlerin sırasını göz ardı etmek istemezseniz, o zaman değerleri ikiye ayırmalısınız. Set nesneleri kullanarak bunları kullanarak equals().


11
2018-06-07 13:42



Değerleri bir kümeye koyarsanız, kopyaları çıkarırsınız ... Aynı öğeler olup olmadığını denetlemezsiniz, yalnızca aynı öğeleri içeriyorlarsa. OP'nin istediği bu olabilir veya olmayabilir. Ama bence, bir liste 3 x içerir ve biri sadece 2 içeriyorsa, aynı değildir. - kgrad
İlk önce iki listenin uzunluğunu kontrol et, sonra istediğin buysa setlere dök. - Lizzan
@ Lizzan: Bu da işe yaramaz. ["A", "a", "b"] ve ["a", "b", "b"] listeleri aynı uzunluklara sahiptir, kümelere dönüştürülürse eşit olur, ancak yine de herhangi bir makul için eşit değildir Eşitliğin tanımı. - jarnbjo
Doğru, ama eğer OP bunu kontrol etmek istiyorsa, Joachim ilk önce söylediği gibi, eşittir (). Öte yandan, bu benim önceki yorumumu da oldukça rahatsız ediyor. - Lizzan


@Joachim Sauer cevabında belirttiği gibi, listeler eşitse ve içerikleri düzgün bir şekilde uygulandığında eşittir. Ancak, kontrol için kullanmıyor olduğundan, öğeler "sipariş" ile aynı değilse işe yaramaz. Bu anlamda, @jarnbjo tarafından belirtilen "katı" eşitliği kontrol eder.

        //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;
            }
        }

Ancak, biraz farklı bir davranış istedim, siparişe ya da bunun gibi bir şeye önem vermedim. Tek istediğim, ikisinin de aynı şeyi içermediğinden emin olmaktı. Çözümüm,

    //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

Bu, iki kez döngüye girdiğinden, daha az performanslıdır. removeAll ve sonra contains tarafından denir removeAll.

Listemin kısa olması garanti edildi, bu yüzden isabet aldırmadım.


2
2017-08-22 22:22





Onları string'e dönüştürebilir ve

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

1
2018-01-02 19:37



.ToString, tüm içerilen nesnelerde uygulanmazsa iyi olmaz. - Bill K


Aşağıda gösterildiği gibi Arraylist'i de kontrol edebilirsiniz:

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);
}

Sayesinde @Jacob


-1
2018-03-05 13:48



doğrudan alınan bu cevap - SymbolixAU