2

名前+数値にバインドされた値を保存したい。たとえば、(John、1)(RED)と(John、2)(BLUE)と(Elize、1)(GREEN)では、一意に組み合わされた2つのキーをどのように保存できますか?

4

4 に答える 4

5

複合キー (ここでは名前と番号) を表す新しい型を作成します。hashCode()とをオーバーライドする必要がありますequals()。型を不変にすることを強くお勧めします。例えば:

public final class NameIntPair {
    private final int intValue;
    private final String name;

    public NameIntPair(int intValue, String name) {
        this.intValue = intValue;
        this.name = name;
    }

    @Override
    public int hashCode() {
        int hash = 17;
        hash = hash * 31 + intValue;
        hash = hash * 31 + (name == null ? 0 : name.hashCode());
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof NameIntPair)) {
           return false;
        }
        if (this == obj) {
           return true;
        }
        NameIntPair other = (NameIntPair) obj;
        return other.intValue == intValue && Objects.equal(other.name, name);
    }
}

Objects.equalここで明示的な nullity チェックを避けるために、便宜上 from Guava を使用しています。Guava を使用していない場合は、同等のものを使用するか、コードで nullity を処理する必要があります。または、null 名を防止して、コンストラクターでこれを検証することもできます。

于 2012-09-28T06:53:27.240 に答える
2

組み合わせの一意性に確信があり、キー オブジェクトを簡単に文字列化できる場合は、文字列連結を使用します。キーを結合するために特殊文字を使用する場合があります (「John#1」と「John#2」など)。

よくわからない場合は、Guava's Tableを使用します。

通常、一度に複数のキーのインデックスを作成しようとすると、Map(FirstName, Map(LastName, Person)) のようなものになってしまい、見苦しく使いにくいものになります。Guava は、任意の「行」タイプと「列」タイプのこのユース ケースをサポートする新しいコレクション タイプ テーブルを提供します。

したがって、テーブルは

行キーと列キーと呼ばれるキーの順序付けられたペアを単一の値に関連付けるコレクション。

于 2012-09-28T07:01:52.607 に答える
1

次のように特定の Key クラスを定義します。

public class Key {
    final String name;
    final int number;
    public Key(String name, int number) {
        this.name = name;
        this.number = number;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + getOuterType().hashCode();
        result = prime * result
                + ((name == null) ? 0 : name.hashCode());
        result = prime * result + number;
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Key other = (Key) obj;
        if (!getOuterType().equals(other.getOuterType()))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (number != other.number)
            return false;
        return true;
    }
    private Test getOuterType() {
        return Test.this;
    }
 }

重要な点は、equals と hashCode のコントラクトを尊重して、コレクション (キーを使用する任意の標準コレクション) が意図したとおりに機能するようにすることです。

ここでは、Eclipse によって生成されたメソッドを単純に使用しましたが、このトピックに役立つ多くの動的ユーティリティ (Guava など) もあります。

于 2012-09-28T06:55:21.680 に答える
0

この場合に適した連結キーを使用した簡単な代替アプローチもあります。

public static String getKey(String name, int number) {
    return name + number;
}

名前が長すぎない場合、文字列連結のオーバーヘッドは、他の回答で提案されている複合キー オブジェクトを作成する場合よりも大きくなりません。

于 2012-09-28T07:04:48.380 に答える