LoginSignup
1
1

More than 5 years have passed since last update.

StringBuffer(StringBuilder)がHashSetにうまく入らない

Last updated at Posted at 2016-05-01

やりたかったこと

単純に、StringBuffer型の文字列をHashSetに入れたかった

何がダメか

StringBuffer(StringBuilder)はequals()とhashCode()がOverrideされておらず、hashの比較がうまくいっていなかったため  

追記

StringBufferの場合

// StringBuffer
Set<StringBuffer> bufferSet = new HashSet<>();
StringBuffer sb = new StringBuffer("");

for (int i = 0; i < 10; i++){
   sb.setLength(0);
   sb.append("test" + i);
   bufferSet.add(sb);
}

bufferSet.forEach(s -> System.out.println(s));

//結果
test9

よく考えたら、同じObjectの中身を変更しているだけなので、当然の結果でした。
下記の内容は、合わせて調べた内容ですので参考程度に載せておきます。


StringBufferの場合は、Java.lang.Objectのequalsが利用されているため(下記)、Objectの比較のみです。

java.lang.Object.java
public boolean equals(Object obj) {
    return (this == obj);
}

以下の方が有用な例です。

Set<StringBuffer> sbSet = new HashSet<>();
sbSet.add(new StringBuffer("abc"));
sbSet.add(new StringBuffer("abc"));
sbSet.add(new StringBuffer("abc"));
sbSet.add(new StringBuffer("abc"));        

sbSet.forEach(s -> System.out.println(s));
//結果
abc
abc
abc
abc

Objectの比較のみであるので、中の文字列が同じでもイコール判定されない。

Stringの場合

// String
Set<String> stringSet = new HashSet<>();
String st = "";

for(int i = 0; i < 10; i++){
   st = "test" + i;
   stringSet.add(st);
}

stringSet.forEach(s -> System.out.println(s));
//結果
test4
test5
test2
test3
test8
test9
test6
test7
test0
test1

Stringは、毎回新しいObjectが生成されるため当然、Setに新しく入る。
ちなみにあまり関係ないですが、Stringのequalsは以下のようになっています。

java.lang.String.java
public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
}

参考

A Set in java never allows duplicates, but it takes StringBuffer objects with the same argument. Why?

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1