ArrayList'in include () yöntemi nesneleri nasıl değerlendirir?


303

Tek bir nesneyi oluşturmak ve kardeşime karşı eklemek Say ArrayList. Daha sonra tam olarak aynı yapıcı girdisine sahip başka bir nesne oluşturursam, contains()yöntem iki nesneyi aynı olarak değerlendirir mi? Yapıcı'nın girişle komik bir şey yapmadığını ve her iki nesnede saklanan değişkenlerin aynı olduğunu varsayalım.

ArrayList<Thing> basket = new ArrayList<Thing>();  
Thing thing = new Thing(100);  
basket.add(thing);  
Thing another = new Thing(100);  
basket.contains(another); // true or false?

class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    equals (Thing x) {
        if (x.value == value) return true;
        return false;
    }
}

Geri dönüş classiçin bu nasıl uygulanmalı ?contains()true

Yanıtlar:


339

ArrayList implementsArayüzünü listeleyin.

Eğer bakarsak için JavadocList en containsyöntemle bunu kullandığını göreceksiniz equals()iki nesnenin aynı olup olmadığını değerlendirmek için bir yöntem.


61
Equals () öğesini geçersiz kılmayı planlıyorsanız, hashcode () yöntemini de geçersiz kıldığınızdan emin olun. Alışmazsanız, Koleksiyonlar kullanılırken işler beklendiği gibi çalışmayabilir mi?
Mohd Farid

34
Bu doğru bir cevaptır, ancak bir Objectyerine kabul etmek için eşittir yönteminizi değiştirmeniz gerektiğini unutmayın Thing. Bunu yapmazsanız, eşittir yönteminiz kullanılmaz. :)
mdierker

1
Sadece kendim için tutulması Kaynak menüsü altında "hashCode () oluştur ve eşittir" olduğunu keşfetti.
Volodymyr Krupach

Bu, başlıktaki soruya cevap verir, ancak açıklamadaki soruya cevap vermez, yani "Daha sonra aynı yapıcı girdisine sahip başka bir nesne oluşturursam, include () yöntemi iki nesneyi aynı olarak değerlendirir mi?"
17'de robguinness

3
Collectionsişlerini optimize edilmiş bir şekilde yapın, yani contains()önce hashCodeiki nesnenin s'sini kontrol eder ve ancak daha sonra çağırır equals(). Eğer hashCodes (her zaman iki farklı örnekler için durum olan farklıdır Thing)equals() yöntem adı edilmeyecektir. Genel bir kural olarak, geçersiz kıldığınızda equals(), geçersiz kılmayı hashCode()da unutmamalısınız .
Sevastyan Savanyuk

52

Bence doğru uygulamalar

public class Thing
{
    public int value;  

    public Thing (int x)
    {
        this.value = x;
    }

    @Override
    public boolean equals(Object object)
    {
        boolean sameSame = false;

        if (object != null && object instanceof Thing)
        {
            sameSame = this.value == ((Thing) object).value;
        }

        return sameSame;
    }
}

1
ififadesi gereksizdir. instanceofyeterlidir.
Paul

@Paul ifadenin hangi bölümünden bahsediyorsunuz?
ChristopheCVB

4
object != nullÇünkü durum, gereksiz object instanceof Thingnesne değil varlık denetler çok boş.
Alexander Farber

15

ArrayList, eşitler karşılaştırmasını yapmak için sınıfta uygulanan eşitler yöntemini (sizin durumunuz Thing sınıfınız) kullanır.


12

Genellikle , performans artışı için bile olsa, hashCode()her geçersiz kılma işleminizde geçersiz equals()kılmalısınız. HashCode()karşılaştırma yaparken nesnenizin hangi 'kovaya' ayrıldığına karar verir, bu nedenle equal()true olarak değerlendirilen iki nesne de aynı şekilde dönmelidir hashCode value(). Varsayılan davranışını hatırlayamıyorum hashCode()(0 döndürürse, kodunuz yavaş çalışmalı, ancak adresi döndürürse kodunuz başarısız olur). Ben hashCode()olsa geçersiz kılmayı unuttum çünkü benim kod başarısız olduğunda bir demet hatırlıyorum . :)


7

Nesnelerde eşittir yöntemini kullanır. Bu nedenle Thing geçersiz kılmalar nesnelere depolanmış değişkenleri eşitlemek ve karşılaştırma için kullanmadığı sürece, contains()yöntemde true değerini döndürmez .


6
class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    equals (Thing x) {
        if (x.value == value) return true;
        return false;
    }
}

Yazmalısınız:

class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    public boolean equals (Object o) {
    Thing x = (Thing) o;
        if (x.value == value) return true;
        return false;
    }
}

Şimdi çalışıyor ;)


6
Yapmamalısınız Şey x = (Şey) o; önce diğer nesnenin boş olup olmadığını kontrol etmeden
steelshark

5

valueİlkel bir tür olmadığında aşağıdaki uygulamanın yanlış olduğunu belirtmek istedim :

public class Thing
{
    public Object value;  

    public Thing (Object x)
    {
        this.value = x;
    }

    @Override
    public boolean equals(Object object)
    {
        boolean sameSame = false;

        if (object != null && object instanceof Thing)
        {
            sameSame = this.value == ((Thing) object).value;
        }

        return sameSame;
    }
}

Bu durumda aşağıdakileri öneriyorum:

public class Thing {
    public Object value;  

    public Thing (Object x) {
        value = x;
    }

    @Override
    public boolean equals(Object object) {

        if (object != null && object instanceof Thing) {
            Thing thing = (Thing) object;
            if (value == null) {
                return (thing.value == null);
            }
            else {
                return value.equals(thing.value);
            }
        }

        return false;
    }
}

kopyasını ortadan kaldırırken bunu nasıl uygulayabilirim?
Sujay

4

Diğer posterler, include () işlevinin nasıl çalıştığı sorusunu ele almıştır.

Sorunuzun eşit derecede önemli bir yönü eşittir () yönteminin nasıl doğru şekilde uygulanacağıdır. Ve bunun cevabı gerçekten bu sınıf için nesne eşitliğini neyin oluşturduğuna bağlıdır. Verdiğiniz örnekte, her ikisinde de x = 5 olan iki farklı nesneniz varsa, bunlar eşit mi? Gerçekten ne yapmaya çalıştığınıza bağlı.

Yalnızca nesne eşitliği ile ilgileniyorsanız, varsayılan .equals () (Object tarafından sağlanan) uygulaması yalnızca kimliği kullanır (yani this == other). İstediğiniz buysa, sınıfınıza equals () uygulamayın (Object'ten devralmasına izin verin). Yazdığınız kod, kimlik için gidiyorsanız bir tür doğru olsa da, hiçbir zaman gerçek bir sınıf b / c'de görünmez, varsayılan Object.equals () uygulamasını kullanmanın hiçbir faydasını sağlamaz.

Bu şeylerle yeni başlıyorsanız, Joshua Bloch'un Etkili Java kitabını şiddetle tavsiye ederim. Harika bir okuma ve bu tür şeyleri kapsar (artı kimlik tabanlı karşılaştırmalardan daha fazlasını yapmaya çalıştığınızda eşittir () nasıl doğru şekilde uygulanır)


Amacım için ArrayList'te eşit değerli bir nesnenin olup olmadığını görmeye çalışıyordum. Sanırım bu bir çeşit hack. Kitap önerisi için teşekkür ederim
Mantas Vidutis

3

JavaDoc kısayolu :

boolean içerir (Object o)

Bu liste belirtilen öğeyi içeriyorsa true değerini döndürür. Daha resmi olarak, yalnızca ve bu liste en az bir öğe e içeriyorsa true değerini döndürür (o == null? E == null: o.equals (e))

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.