2

OCJP 6 試験の問題なので、意図的に完全に正しくはありません (合法ですが)。

与えられたコード:

class ToDos {
    String day;

    public ToDos(String d) {
        day = d;
    }

    public boolean equals(Object o) {
        return ((ToDos) o).day == day;
    }

    public int hashCode() { return 9; }
}

public class MapEQ {

    public static void main(String[] args) {
        Map<ToDos, String> map = new HashMap<ToDos, String>();

        ToDos t1 = new ToDos("Monday");
        ToDos t2 = new ToDos("Mond" + "a" + "y");
        ToDos t3 = new ToDos("Tuesday");

        map.put(t1, "a");
        map.put(t2, "b");
        map.put(t3, "c");

        System.out.println(map.size());
    }

}

なぜ出力は 2 なのですか? つまり、equalsメソッドは正しくオーバーライドされていないため、t1.day == t2.dayfalse であるはずです! 私は何かを見逃していますか?

4

2 に答える 2

7

その理由は:

"Mond" + "a" + "y"

コンパイル時に "月曜日" に評価されるため、文字列プール内のインスタンスは 1 つだけになります。この動作を調べるためのもっと簡単なテストがあります:

System.out.println("Mond" + "a" + "y" == "Monday");  //true

String y = "y";
System.out.println("Mond" + "a" + y == "Monday");  //false

final String y2 = "y";
System.out.println("Mond" + "a" + y2 == "Monday");  //true

上記の例は、コンパイラが文字列連結をどのように扱うかについての概要を示しているはずです。

そして、安全のために、常に以下を使用してください。

return ((ToDos) o).day.equals(day);
于 2012-12-09T11:06:10.627 に答える
1

以前の回答に追加するだけです...要点を示す別の例:

String a = "Monday";
String b = new String("Monday");
String c = "Monday";

(a == b)      // false
(a.equals(b)) // true

(a == c)      // true
(a.equals(c)) // true

と の両方が String プール内の同じオブジェクトac指しています。

于 2012-12-09T11:35:55.340 に答える