You just need to know when the String's functions return the same reference (without creating new one). As usual it's the case when nothing has to be changed (i.e. "str".trim() nothing to trim, so in that case "str" == "str".trim();
"str".toLowerCase()== "str"; TRUE
"str".replace("a", "c") == "str"; TRUE
"str".concat("") == str; TRUE and so on.
String's toString() method returns always the same reference, so
"string" == "string".toString(); always TRUE.
For the case of "string" == "str" + "ing"; (TRUE) I have not a good explanation but I found that "+" works quasi the JVM sees the whole
word at once.
So, "s" + "t" + "r" + "i" + "n" + "g" == "string" always TRUE.
I think you know why "string" == "string" (from a pool of String literals).