IT

[Java]Mapのkeyに自作クラスを指定するときの注意

プロフィール画像

まる

5歳の長男と楽しく暮らすシングルファーザーです。 父親目線での育児、家事について発信していきます。ひとり親家庭や父親に寄り添った情報を増やしたい、という思いで活動を始めました。 趣味はスポーツ観戦と晩酌。成長した息子とビール片手にスポーツ観戦することが、小さな夢です。

久々にJavaでプログラム書きました。

なかなか勘が鈍っているのか、Mapのkey操作ではまってしまったので、メモしておきます。

やりたいこと

Mapのkeyとvalueに自作クラスを使って、containsKey()やput()をしてみます。

こんな感じです。

Map templateMap = new HashMap<>();
class TemplateKey {
    private int key1;
    private int key2;
}
class TemplateValue {
    private int value1;
    private int value2;
}

ここまでは、簡単にできると思っていました。。

発生した問題

今考えると、「そりゃそうだよな」と思います。。

1つデータをputして、containsKey()でkeyを検索したがひっかからない。

containsKey()って引数がObject型で、intでもStringでも検索してくれるイメージでしたが、今回のような自作クラスのObjectだと、このままでは検索できないんですね。

Map templateMap = new HashMap<>();
TemplateKey key = new TemplateKey(1, 2);
TemplateKey value = new TemplateValue(3, 4);
templateMap.put(key, value);

// 検索するkey
TemplateKey searchKey = new TemplateKey(1, 2);

templateMap.containsKey(searchKey)  // false

TemplateKeyクラスのオブジェクトを新しく生成して、それをcontainsKey()の引数に指定するとfalseになります。

まあ、Stringの比較の時と同様に、オブジェクト比較になっているからなんでしょうね。。

put()やget()も同様に、今回やりたいことがオブジェクト比較によってできなくなっていました。

解決するためにやったこと

解決方法は簡単でした。

TemplateKeyクラスのequals()とhashCode()を、オーバーライドして処理を書き換えてあげれば解決できました。

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof TemplateKey) {
            TemplateKey condition = (TemplateKey) obj;
            return this.key1.equals(condition.key1) 
                    && this.key2.equals(condition.key2);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return Objects.hash(key1, key2);
    }
  • この記事を書いた人
プロフィール画像

まる

5歳の長男と楽しく暮らすシングルファーザーです。 父親目線での育児、家事について発信していきます。ひとり親家庭や父親に寄り添った情報を増やしたい、という思いで活動を始めました。 趣味はスポーツ観戦と晩酌。成長した息子とビール片手にスポーツ観戦することが、小さな夢です。

HOT

-IT