2011/11/06

StringBuffer (CharSequence) の罠

Project Eulerをやっていて、StringBuffer(正確には、StringBufferの親インターフェースCharSequence)の罠にはまった。悔しい。備忘のため記しておく。
回文の問題で、reverse()が使いたいがためにStringをStringBufferにコピーしたのだが、StringBufferオブジェクト同士をequalsで比較しようとしてミスった。


StringBuffer(やStringBuilder)ではequals(やhashCode)はオーバーライドされていないため、オブジェクトの値はequalsで比較できない。Setの要素やMapのキーにすることもできない。 参照:http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/lang/CharSequence.html

たとえば、以下のソースでは、sb1とsb2の値は同じだが、
public class StringBufferTrap
{
    public static void main(String[] args)
    {
 StringBuffer sb1 = new StringBuffer("abc");
 StringBuffer sb2 = new StringBuffer("abc");
 
 System.out.println("sb1: " + sb1);
 System.out.println("sb2: " + sb2);
 System.out.println("sb1 == sb2: " + sb1.equals(sb2));
    }
}
equals()で比較すると false となる。

比較したい場合は、toString()などでString型にすること望ましいだろう。
そもそもStringBuffer・StringBuilderは文字列を「作る」クラスであるという認識が足りなかったのが敗因だ。

Javaは手強いな。
いや、equalsくらい定義しといてほしかったところなんだけど。。。ダメな理由は何かあったのかしら。

0 件のコメント: