316

1 つのオブジェクトを作成し、それを my に追加するとしますArrayList。次に、まったく同じコンストラクター入力で別のオブジェクトを作成した場合、contains()メソッドは 2 つのオブジェクトを同じであると評価しますか? コンストラクターが入力に対して何もおかしいことをせず、両方のオブジェクトに格納されている変数が同一であると仮定します。

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

これはreturnclassを実装する方法ですか?contains()true

4

10 に答える 10

357

ArrayListimplementsリスト インターフェイス。

メソッドのJavadoc をList見ると、メソッドをcontains使用してequals()2 つのオブジェクトが同じかどうかを評価していることがわかります。

于 2010-04-15T04:23:14.767 に答える
55

正しい実装は

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;
    }
}
于 2012-10-31T19:27:11.190 に答える
14

ArrayList は、クラス (あなたのケースの Thing クラス) に実装された equals メソッドを使用して、equals 比較を行います。

于 2010-04-15T03:47:04.647 に答える
12

一般に、パフォーマンスを向上させるためだけであっても、オーバーライドhashCode()するたびにオーバーライドする必要があります。は、比較を行うときにオブジェクトがソートされる「バケット」を決定するため、true と評価される 2 つのオブジェクトは同じ を返す必要があります。のデフォルトの動作を思い出せません(0 が返された場合、コードはゆっくりと動作するはずですが、アドレスが返された場合、コードは失敗します)。ただし、オーバーライドするのを忘れたためにコードが失敗したことを何度も覚えています。:)equals()HashCode()equal()hashCode value()hashCode()hashCode()

于 2010-04-15T07:30:09.157 に答える
7

オブジェクトに対して equals メソッドを使用します。そのため、Thing が equals をオーバーライドし、比較のためにオブジェクトに格納されている変数を使用しない限り、contains()メソッドで true は返されません。

于 2010-04-15T03:48:20.430 に答える
6
class Thing {  
    public int value;  

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

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

あなたは書く必要があります:

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

今では動作します;)

于 2012-09-10T08:07:49.860 に答える
6

valueがプリミティブ型でない場合、次の実装は間違っていることに注意してください。

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

その場合、私は次のことを提案します。

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;
    }
}
于 2013-11-21T12:06:45.257 に答える
4

他のポスターは、contains()がどのように機能するかについての質問に取り組んでいます。

質問の同様に重要な側面は、equals()を適切に実装する方法です。そして、これに対する答えは、この特定のクラスのオブジェクトの同等性を構成するものに実際に依存しています。提供した例では、両方ともx = 5の2つの異なるオブジェクトがある場合、それらは等しいですか?それは本当にあなたがやろうとしていることに依存します。

オブジェクトの同等性のみに関心がある場合、.equals()のデフォルトの実装(Objectによって提供されるもの)はIDのみを使用します(つまり、this == other)。それが必要な場合は、クラスにequals()を実装しないでください(Objectから継承させてください)。あなたが書いたコードは、アイデンティティを求めているのであれば正しいものですが、実際のクラスb / cには表示されませんが、デフォルトのObject.equals()実装を使用するよりもメリットはありません。

このようなことを始めたばかりの場合は、JoshuaBlochによるEffectiveJavaの本を強くお勧めします。これは素晴らしい読み物であり、この種のことをカバーしています(さらに、IDベースの比較以上のことを行おうとしているときにequals()を正しく実装する方法)

于 2010-04-15T05:55:06.610 に答える
3

JavaDocからのショートカット:

boolean contains(オブジェクト o)

このリストに指定された要素が含まれている場合、true を返します。より正式には、このリストに(o==null ? e==null : o.equals(e))となる要素 e が少なくとも 1 つ含まれている場合にのみ true を返します。

于 2015-10-01T11:49:08.813 に答える