2016-05-12 2 views
1

単純に3つのインターフェイスオブジェクトで構成された少し(Java)クラスがあるとします。これら3つのオブジェクトが一緒にマップのキー値を構成します。今、私の質問は、クラスのequalsとhashcodeを定義する方法ですか?つまり、そのクラスのすべてのメンバーは、何も実装していないインターフェースだけですか?あなたのオブジェクトがインターフェイスだけで構成されている場合、hashcodeとequalsを定義する方法は?

例:

class SomeKey { 
    public SomeKey(SomeWeiredInterface1 a, SomeWeiredInterface2 b,  SomeWeiredInterface3 c){ 
    .... 
} 
} 

最も単純な方法は、次のようになります。

public boolean equals(Object other){ 
SomeKey otherKey = (SomeKey)other; 

return a.equals.otherKey.a && b.equals.otherKey.b && c.equals.otherKey.c; 
} 

私にとってそれは単に不可能ですように見える、または少なくとも私は自分でこれらのメソッドを記述する必要がありますなぜなら、これらのインタフェースの実装のハッシュコードまたは同等のメソッドを使用(または委譲)できないからです。

ありがとうございました! はThorsten

+1

なぜ:

は、例を参照してください?これらのオブジェクトに対して 'equals'と' hashCode'を完全に細かく呼び出すことができます。 –

+0

これで、インターフェイスを実装するオブジェクトでequalsまたはhashCodeが実行されますか?それは意味をなさないでしょう;-)一方、equalsとhashCodeはインタフェース定義の一部ではありませんか? – user1119859

+0

はいとはい。だから何?これらのメソッドを定義していないインタフェースとして型指定されたオブジェクトに対しては、 'equals'と' hashCode'を呼び出すことができます。 –

答えて

1

これらに等しい(である)とhashCode私のIDEによってautomaticllyに生成された()メソッド:

public class SimpleClass { 
private SimpleFirstInterface firstField; 
private SimpleSecondInterface secondField; 

@Override 
public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 

    SimpleClass that = (SimpleClass) o; 

    if (firstField != null ? !firstField.equals(that.firstField) : that.firstField != null) return false; 
    return secondField != null ? secondField.equals(that.secondField) : that.secondField == null; 

} 

@Override 
public int hashCode() { 
    int result = firstField != null ? firstField.hashCode() : 0; 
    result = 31 * result + (secondField != null ? secondField.hashCode() : 0); 
    return result; 
} 

}

これらの2つの方法に等しいそれらの内部に使用している()とhashCode( )メソッドを実装しています。そうでない場合は、Objectのequals()およびhashCode()の標準実装が使用されます。

+0

したがって、SimpleFirstInterfaceがクラスSimpleFirstInterfaceImplから実装されている場合、SimpleFirstInterfaceImplからのequalsおよびhashCodeが呼び出されます。 SimpleFirstInterfaceImplがこれらの関数を実装していない場合、Objectからのものが呼び出されますか? – user1119859

+0

うん。正確に。しかし、HashMapを効果的に機能させたい場合は、これらのメソッドの定性的な実装を行い、Objectのものに依存しないようにする必要があります。 –

2

すべてのインターフェイスは、Objectクラスのすべてのパブリックメソッドを暗黙に宣言します(JLS § 9.2参照)。インタフェースタイプのequalshashCodeのメソッドを呼び出すことができ、インタフェースを実装している具体的なクラスでオーバーライドされたメソッドを呼び出すか、Objectから継承したメソッドのデフォルトの実装を呼び出します。

あなたはフィールドタイプは、クラスまたはインタフェースであるかどうかに関係なく、同じようSomeKeyequalshashCodeメソッドを書くことができます。

@Override 
public boolean equals(Object o) { 
    if (o == this) return true; 
    if (!(o instanceof SomeKey)) return false; 
    SomeKey other = (SomeKey)o; 
    return a.equals(other.a) && b.equals(other.b) && c.equals(other.c); 
} 

@Override 
public int hashCode() { 
    return java.util.Objects.hash(a.hashCode(), b.hashCode(), c.hashCode()); 
} 
-1

おそらく、(メソッドのハッシュコードを上書きするようなもの)、(等しいです) compareTo()は、Comparable Interfaceを使用しています。他のインターフェースで試してみる。 私は上記の答えを読んでいない、もちろん良い例です。

private static class SomeString implements Comparable<SomeString> { 
    private final String s; 
    SomeString(final String s) { 
    this.s = s; 
    } 

@Override 
public int compareTo(final SomeString o) { 
return s.compareTo(o.s); 
} 

}

@Override 
public boolean equals(final Object o) { 
    if(o == null) return false; 
    if(this == o) return true; 
    if(this.getClass() != o.getClass()) return false; 

    final SomeString o1 = (SomeString) o; 
    return compareTo(o1) == 0; 
} 

    @Override 
    public int hashCode() { 
    return s.hashCode(); 
    } 

0

あなたは使用(デリゲート)に等しいと実装クラスが、のhashCodeメソッドは、はい、あなたがそれらにを頼らないことができます。

実装クラスには、同一オブジェクトの一意の結果または同じオブジェクトの異なるハッシュコードを生成しないハッシュコード& equalsが含まれている場合があります。

私はこれらの3つのインターフェイスはではなくマーカーインターフェイスであると信じており、実装クラスのメンバ変数の状態を返すメソッドをいくつか持っています。 上記が真であれば、あなた自身のhashcode()&と同じ状態を実装とすることができます。

Interface A{ 
    getValue(); 
} 

Interface B{ 
    getData(); 
} 

class AImpl implements A{ 
     private String value; 

     public String getValue(){ 
      return value; 
     } 
} 
class BImpl implements B{ 
     private int data; 

     public int getData{ 
      return data; 
     } 
} 

class SomeKey{ 

    private A value; 
    private B data; 

    //constructor 
    public SomeKey(A value, B data){ 
     this.value = value; 
     this.data = data;  
    } 

@Override 
public int hashcode(){ 
    int result = 1; 
    result = 29 * result + value.hashcode(); 
    result = result + data.hashcode(); 
    return result; 
} 
//similarly override equals 
}  
関連する問題