Ответ
В Java строки могут быть разными объектами даже с одинаковым содержимым из-за того, как работает String Pool.
Если строка создана через new String(), она всегда будет новым объектом в куче, даже если такое же значение есть в пуле. При сравнении через == проверяется ссылка, а не содержимое.
String a = "hello"; // попадает в String Pool
String b = new String("hello"); // новый объект в куче
System.out.println(a == b); // false - разные объекты
System.out.println(a.equals(b)); // true - одинаковое содержимое
Для сравнения содержимого всегда используйте equals(). Для интернирования строк можно использовать intern().