そういえば、何年か前に気になったことを思い出したのでメモしておきます。情報のソースを出すことができませんが、実験結果と考察だけ載せておきます。
実験
Javaにおいて、文字列比較をイコール演算子(==)で行うことはできません。これは常識です。しかし、このような場合は、成立してしまうようです。
class StringEqualsTest{
public static void main(String[] args){
String a = "aaa";
String b = "aaa";
if(a == b) System.out.println("match");
else System.out.println("no-match");
}
}
// > match
Javaにおいて、同じリテラル(定数)が存在する場合、それらは同じオブジェクトとして扱われます。そのため、このような実験結果になるわけです。
一方、こうやると期待通り(?)の結果を得ることができます。
class StringEqualsTest{
public static void main(String[] args){
String a = new String("aaa");
String b = "aaa";
if(a == b) System.out.println("match");
else System.out.println("no-match");
}
}
// > no-match
これは、文字列オブジェクトが新しく作成されるからですね。
次のようなことをやっても、違うオブジェクトと判断されます。
class StringEqualsTest{
public static void main(String[] args){
String a = "aaa";
String b = "aaa";
a = a + "";
if(a == b) System.out.println("match");
else System.out.println("no-match");
}
}
// > no-match
これはなぜでしょうか。Javaにおいて内部的な文字列連結処理は、「ふたつの文字列をつなげた新しい文字列を格納するStringオブジェクトを作成する」となっているからです。そのため、文字列連結をループの中で過剰に何度も行うと、newを何度も行っていることと同意なので、パフォーマンスが下がります(オブジェクトの作成は手間がかかる処理なため)。
どうすればいいの
当然のごとく、String.equals()を使います。
class StringEqualsTest{
public static void main(String[] args){
String a = new String("aaa");
String b = "aaa";
if(a.equals(b)) System.out.println("match");
else System.out.println("no-match");
}
}
// > match