2

It is question from OCJP 6 exam, so it is intentionally not fully correct (but legal).

Given code:

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

}

Why output is 2? I mean, equals method is not overriden corretcly, so t1.day == t2.day supposed to be false! Am I'm missed something?

Charles
  • 50,010
  • 13
  • 100
  • 141
Dmitry Zaytsev
  • 23,526
  • 13
  • 92
  • 141

2 Answers2

7

It's because:

"Mond" + "a" + "y"

is evaluated at compile time to "Monday" thus resulting in just one instance in string pool. There is a much simpler test to examine this behavior:

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

Examples above should give you some overview on how the compiler treats string concatenation.

And to be on the safe side, always use:

return ((ToDos) o).day.equals(day);
Tomasz Nurkiewicz
  • 324,247
  • 67
  • 682
  • 662
1

Just adding to previous answers ... another example illustrating the point:

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

Both a and c point to the same object in the String pool.

xagyg
  • 9,304
  • 2
  • 29
  • 28