- ベストアンサー
Listデータを重複せずにSetに格納できるか?
- ListにUserFormBean_2クラスを格納し、UserIdをキーにして重複せずにSetに格納できるかを検証する。
- UserFormBean_2クラスには、userNum、userId、passwordのフィールドがあり、それぞれのフィールドに値を設定できる。
- 実行ソースコードでは、UserFormBean_2クラスのインスタンスを生成し、UserIdとPasswordに値をセットしてListに格納する。また、Setにも同じインスタンスを格納する。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
> 一般的にSetはあまり使わない方がいいのでしょうか? ケース・バイ・ケースだと思います。 String や Integer などの様に等価性が明確なオブジェクトを格納するので有れば、Setを使うことは問題有りません。 もし、UserFormBean_2 で userId が一意性を表すフィールドであれば、先の equals と hashCode の実装に問題は無く、したがってSetを使うことに問題は有りません。 言い換えれば、 userId が同じ UserFormBean_2 オブジェクトは他のフィールドも同じになるべきなのであれば、Setを使うことに問題は無いでしょう。 逆に、userId が同じでuserNumかpasswordの異なるオブジェクトがいくつか有り、その中から最初のものを取り出すのであれば、先の equals と hashCode の実装は間違いであり、 Mapを使うべきでしょう。 なお、 Map を使う場合でも、キーとするオブジェクトは (Setの要素と同様に) 等価性が明確なものを選ぶ必要が有ります。 JDKのソースを見れば分かりますが、実際に HashSet は HashMap を使って実装されています。
その他の回答 (3)
- mononoke99
- ベストアンサー率40% (2/5)
UserFormBean_2#userIdをキーとするjava.util.HashMapを使いましょう。 キーの評価はHashMap#containsKey(Object)を使用すればよいです。 UserFormBean_2 bean1 = new UserFormBean_2(); bean1.setUserId("user1"); UserFormBean_2 bean2 = new UserFormBean_2(); bean2.setUserId("user2"); UserFormBean_2 beanAdd = new UserFormBean_2(); beanAdd.setUserId("user1"); Map map = new HashMap(); map.put(bean1.getUserId(), bean1); map.put(bean2.getUserId(), bean2); if (!map.containsKey(beanAdd.getUserId())) { map.put(beanAdd.getUserId(), beanAdd); } System.out.println(map); 格納コンテナ側のアクセサに評価実装を追加するならまだしも Entity側に依存した実装を追加するのはお世辞にもよいデザインとは言えません。 もしSetオブジェクトを最終的に生成したいのであれば Set.addAll(Collection)を使用し Set set = new HashSet(); set.addAll(map.values()); とすればよいです。
補足
解答ありがとうございます 試してみました。 その際、 mapにuserFormBeanクラスデータを格納時、 すでにkeyが同じなら、その時に格納されないようになっているようなのですが、 一般的にSetはあまり使わない方がいいのでしょうか? 今回だと、Mapでいけると思ったので。。 よろしくお願いします。
- root139
- ベストアンサー率60% (488/809)
> boolean isExists = uf.equals( uB.getUserId()); は、UserFormBean_2 と String を比べているので、必ず false になりますよ。 boolean isExists = uf.equals( uB ); か、 boolean isExists = uf.getUserId().equals( uB.getUserId() ); では?
お礼
解答ありがとうございます。 無事解决できました。 ありがとうございました。
- root139
- ベストアンサー率60% (488/809)
端的に言えば、UserFormBean_2 で equals() と hashCode() をオーバーライドして、userId のみによってそれらの戻り値を導出すれば、Set に格納したものは userId が一意となります。 ただし、 equals() と hashCode() をオーバーライドすると言うことは、そのクラスの等価性を定義することになります。 つまり 「userId の値が同じであれば、UserFormBean_2オブジェクト自体も等しいと見なす」 と決めたことになります。 例) --------------------------------------------------------------------- public class UserFormBean_2 { ・ ・ ・ public int hashCode() { return userId != null ? userId.hashCode() : 0; } public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof UserFormBean_2)) return false; UserFormBean_2 other = (UserFormBean_2) obj; if (userId == null) return other.userId == null; return userId.equals(other.userId); } } -------------------------------------------------------------------------
補足
さっそくの解答ありがとうございます。 参考URL確認してみました。 それで試してみたのですが、 List内のデータとSet内のデータが等しい時に「true」を返ってきません。 作成手順は以下です。 //UserFormBean_2クラスのインスタンス UserFormBean_2 uB = new UserFormBean_2(); UserFormBean_2 uf = new UserFormBean_2(); //List内のループ for(Iterator a=array2.iterator();a.hasNext(); ) { uB = (UserFormBean_2)a.next(); System.out.println("list_Value:"+uB.getUserId()); //Set内のループ for(Iterator s=ss.iterator();s.hasNext(); ) { uf = (UserFormBean_2)s.next(); System.out.println("set_Value:" + uf.getUserId()); //データのSet内での有無 boolean isExists = uf.equals( uB.getUserId())); } } UserFormBean_2クラスには、equals()メソッドとhashCode()メソッドを提示してもらった通りでオーバーライドしています。 よろしくお願いします。
お礼
丁寧な解答ありがとうございます。 大変助かりました。 ありがとうございました。