Listデータを重複せずにSetに格納できるか?

このQ&Aのポイント
  • ListにUserFormBean_2クラスを格納し、UserIdをキーにして重複せずにSetに格納できるかを検証する。
  • UserFormBean_2クラスには、userNum、userId、passwordのフィールドがあり、それぞれのフィールドに値を設定できる。
  • 実行ソースコードでは、UserFormBean_2クラスのインスタンスを生成し、UserIdとPasswordに値をセットしてListに格納する。また、Setにも同じインスタンスを格納する。
回答を見る
  • ベストアンサー

Listデータを重復せずにSetに格納したい

お世話になっています。 以下のクラスがあるとき public class UserFormBean_2 { private int userNum; private String userId; private String password; public void setUserNum(int userNum) { this.userNum = userNum; } public int getUserNum() { return this.userNum; } public void setUserId(String userId) { this.userId = userId; } public String getUserId() { return this.userId; } public void setPassowd(String password) { this.password = password; } public String getPassword() { return this.password; } public String toString() { return this.userId; } } Listにこのクラスが格納されている場合、 userIdをキーに、userIdを重複せずに格納することは可能なのでしょうか? 実行ソースは以下です。 public class Run{ public static void main(String[] args){ Set ss = new HashSet(); List array2 = new ArrayList(); (データ1) UserFormBean_2 userFr = new UserFormBean_2(); userFr.setUserId("maki"); userFr.setPassowd("なつのおとしご"); array2.add(userFr); //仮に、先にSetに値を格納する ss.add(userFr); (データ2) userFr = new UserFormBean_2(); userFr.setUserId("sayaka"); userFr.setPassowd("motomiti"); array2.add(userFr); (データ3) userFr = new UserFormBean_2(); userFr.setUserId("neneko"); userFr.setPassowd("ゆずは!"); array2.add(userFr); (データ4) userFr = new UserFormBean_2(); userFr.setUserId("森の山手"); userFr.setPassowd("なつのおとしご"); array2.add(userFr); //仮にSetに値を格納する ss.add(userFr); (データ5) userFr = new UserFormBean_2(); userFr.setUserId("maki"); userFr.setPassowd("なつのおとしご"); array2.add(userFr); System.out.println("size:"+array2.size()); System.out.println("set_size:"+ss.size()); UserFormBean_2 uB = new UserFormBean_2(); UserFormBean_2 uf = new UserFormBean_2(); System.out.println(" -- set -- "); } } よろしくお願いします。 for( Iterator u=array2.iterator();u.hasNext(); ) { uB = (UserFormBean_2)u.next(); System.out.println(uB.getUserId()); for(Iterator s=ss.iterator();s.hasNext(); ) { uf = (UserFormBean_2)s.next(); System.out.println(uf.getUserId()); ss.add(uB); }

  • Java
  • 回答数4
  • ありがとう数15

質問者が選んだベストアンサー

  • ベストアンサー
  • root139
  • ベストアンサー率60% (488/809)
回答No.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 を使って実装されています。

kannitiha
質問者

お礼

丁寧な解答ありがとうございます。 大変助かりました。 ありがとうございました。

その他の回答 (3)

回答No.3

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()); とすればよいです。

kannitiha
質問者

補足

解答ありがとうございます 試してみました。 その際、 mapにuserFormBeanクラスデータを格納時、 すでにkeyが同じなら、その時に格納されないようになっているようなのですが、 一般的にSetはあまり使わない方がいいのでしょうか? 今回だと、Mapでいけると思ったので。。 よろしくお願いします。

  • root139
  • ベストアンサー率60% (488/809)
回答No.2

> boolean isExists = uf.equals( uB.getUserId()); は、UserFormBean_2 と String を比べているので、必ず false になりますよ。 boolean isExists = uf.equals( uB ); か、 boolean isExists = uf.getUserId().equals( uB.getUserId() ); では?

kannitiha
質問者

お礼

解答ありがとうございます。 無事解决できました。 ありがとうございました。

  • root139
  • ベストアンサー率60% (488/809)
回答No.1

端的に言えば、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:
http://www.ibm.com/developerworks/jp/java/library/j-jtp05273/
kannitiha
質問者

補足

さっそくの解答ありがとうございます。 参考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()メソッドを提示してもらった通りでオーバーライドしています。 よろしくお願いします。

関連するQ&A

  • Iteratorの使用について

    いつもお世話になっています。 List使用時の、iterator方法について質問します。 Listに、以下の情報が入っている場合で、 UserFormBean userFormBean = new UserFormBean(); List array = new ArrayList(); array.add("ほのか"); array.add("なぎさ"); array.add("桃子"); array.add("雛菊"); array.add("百合"); array.add("陽介"); //ListにListを格納する List array2 = new ArrayList(); array2.add("酒蔵"); array.add(array2); //別クラスのデータをListに格納する userFormBean.setUserName("あかね"); userFormBean.setAge(15); /** UserFormBeanクラス **/ public class UserFormBean { private String userName; private int age; public String getUserName() { return this.userName; } public void setUserName(String userName) { this.userName = userName; } public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } } このとき、文字列で入っている場合は、普通に取得できるが、 List毎入っている場合と別クラスが入っているうまく取得できません。 普通にfor()を使用すれば取得できるのですが、 このときiteratorを使用して取得することは可能なのでしょうか? また、一般的にこのような取得方法の場合、forとどちらを使用するべきなのでしょうか? 取得方法は以下です。 for(Iterator a = array.iterator(); a.hasNext();) { System.out.println("a="+a); System.out.println("value="+a.next() ); //このとき、a.next()から再度UserFormBeanクラスデータを取得したい } ◆取得結果 a=java.util.AbstractList$Itr@10b30a7 value=ほのか a=java.util.AbstractList$Itr@10b30a7 value=なぎさ a=java.util.AbstractList$Itr@10b30a7 value=桃子 a=java.util.AbstractList$Itr@10b30a7 value=雛菊 a=java.util.AbstractList$Itr@10b30a7 value=百合 a=java.util.AbstractList$Itr@10b30a7 value=陽介 a=java.util.AbstractList$Itr@10b30a7 value=[酒蔵] a=java.util.AbstractList$Itr@10b30a7 value=UserFormBean@1a758cb 宜しくお願いします。

    • ベストアンサー
    • Java
  • setについてです。毎度ですがよろしくお願いします

    フィールドに「String mailAddress」を追加いたしました。 addCustomerCardメソッドの引数にmailAddressを追加して、メソッドではsetを使ってmailAddressの 重複がないかどうかを確認したいです。 あとは既に存在するmailAddressの場合は例外をスローしたいです。 できれば具体的なプログラムを追加していただけると助かります。 以上何卒よろしくお願い致します。 class CustomerManager { public static void main(String[] args){ CustomerManager manager = new CustomerManager(); manager.addCustomerCard( "山田一郎"); manager.addCustomerCard( "鈴木太郎"); manager.addCustomerCard( "田中次郎"); manager.printAllInfo(); } private CustomerCard[] customers = new CustomerCard[5]; private int index = 0; public void addCustomerCard(String name){ customers[index] = new CustomerCard(1 + index,name); index++; } public void printAllInfo() { System.out.print("ID =" + customers[0].id + ","); System.out.println("名前 = " + customers[0].name); System.out.print("ID =" + customers[1].id + ","); System.out.println("名前 = " + customers[1].name); System.out.print("ID =" + customers[2].id + ","); System.out.println("名前 = " + customers[2].name); } } class CustomerCard { String name; int id; public CustomerCard(int id,String name,String mailAddress){ this.name = name; this.id = id; this.mailAddress = mailAddress; } public String getName(){ return this.name; } public String mailAddress(){ return this.mailAddress; } }

    • ベストアンサー
    • Java
  • エラーを解決したいんですが。

    // Genericsを用いたArrayListを使用し // ループ処理にはiteratorを使用しない。 // for文を使ってリスト中身が奇数の場合はそのまま画面表示。 // 偶数の場合は-1をかけてから画面表示。 import java.util.ArrayList; class Test{ public static void main(String[] args) { //GenericsのInteger型でArrayListのインスタンスを生成 ArrayList<Integer> array = new ArrayList<Integer>(); array.add(1); array.add(2); array.add(3); array.add(4); array.add(5); for(int i=0; i<array.size(); i++) { Integer integer = array.get( i ); //もし値が偶数だったら if(integer % 2 == 0){ integer *= -1; System.out.println( integer ); } //(それ以外)もし値が奇数だったら else{ System.out.println( integer ); } } } } 上記のプログラムで、 >Integer integer = array.get( i ); の場所が、「交換性がない型」と言われ、エラーになってしまうんですが どうしたらいいですか?

    • ベストアンサー
    • Java
  • Javaがうまく動作しない理由

    Java初心者です。 下記のJavaのプログラムで(6)のところで(1)から(4)が呼び出されると(1)と(4)はうまく動作して画面に表示されるのですが(2)(3)がうまく動きません。ソースは長いので全部掲載できませんが、基本的にはほかの部分はうまく動いています。(5)ではうまくテキストフィールドfield2に文字が表示されます。 原因と対処方法を教えてください。 public ChatServer(){ ............ field1 = new TextField("ABC"); field1.setLocation(10,30); field1.setSize(150,25); field1.addActionListener(this); add(field1); field2 = new TextField("DEF"); field2.setLocation(10,60); field2.setSize(150,25); add(field2); ............ public void text1(String ss){ (1) System.out.println("1:*****" + ss); (2) field2.setText(ss); (3) field1.setText("AAA"); (4) System.out.println("2:*****" + ss); } public void actionPerformed(ActionEvent e){ String ss; if(e.getSource() == field1){ ss = field1.getText(); (5) field2.setText(ss); } } } class clientProc implements Runnable { ChatServer serv2 = new ChatServer(); ............. String line = in.readLine(); while (!"quit".equals(line)){ line = in.readLine(); (6) serv2.text1(line); System.out.println("***"); } .............. }

  • ネストされたオブジェクトを取得したい(Java)

    ↓の文はコードの説明です。 Seriesクラスのいう、数の列を入れるクラスを定義しています。 その中にはインスタンス変数Vector arrayがあります。 arrayの中には、Integerと、インスタンス化されたSeriesを入れます。 イメージを書くとこんな感じです↓ 単純にarrayの中身がIntegerのみの場合は、 series[5, 4, 12, 54, 17] のようになります arrayの中身にインスタンス化されたSeriesが入ると、 array[5, array[2, 3], 4] のようかもしれません。 実際のコードは、 import java.util.Vector; class Series{ Vector<Object> array = new Vector<Object>(0); Series(){ array.add(new Integer(5)); array.add(new Series(2, 3)); // ネスト array.add(new Integer(4)); // 全体のarrayを表示 System.out.println(array); // 入れ子になっているarrayを表示 (エラーになります) System.out.println(array.elementAt(1).array); } Series(int a, int b){ array.add(new Integer(a)); array.add(new Integer(b)); } } public class TestSeries { public static void main(String[] args){ new Series(); } } です。 // 入れ子になっているarrayを表示 (エラーになります) System.out.println(array.elementAt(1).array); を消去すれば、 出力結果:[5, Series@7f5f5897, 4] となります。 // 入れ子になっているarrayを表示 (エラーになります) System.out.println(array.elementAt(1).array); を実行した時の目標は 出力結果:[2, 3] となることです。 インデントがなくなって、読みづらいと思いますが、よろしくお願いします。

    • ベストアンサー
    • Java
  • java.util.Listについてです。

    以下の配列プログラムをava.util.Listを使うとどういう感じになるのでしょうか? 何卒ご回答よろしくお願い致します。 class CustomerManager { public static void main(String[] args){ CustomerManager manager = new CustomerManager(); manager.addCustomerCard( "山田一郎"); manager.addCustomerCard( "鈴木太郎"); manager.addCustomerCard( "田中次郎"); manager.printAllInfo(); } private CustomerCard[] customers = new CustomerCard[5]; private int index = 0; public void addCustomerCard(String name){ customers[index] = new CustomerCard(1 + index,name); index++; } public void printAllInfo() { System.out.print("ID =" + customers[0].id + ","); System.out.println("名前 = " + customers[0].name); System.out.print("ID =" + customers[1].id + ","); System.out.println("名前 = " + customers[1].name); System.out.print("ID =" + customers[2].id + ","); System.out.println("名前 = " + customers[2].name); } } class CustomerCard { String name; int id; public CustomerCard(int id,String name){ this.name = name; this.id = id; } public String getName(){ return this.name; } }

    • ベストアンサー
    • Java
  • 動作説明をお願いします。

    ↓このプログラムの動作説明を詳しくお願いします。無名クラスが使われていたり大体はわかるんですが、オブジェクトの名前が同じだったりしてどこで呼び出されてどこにいくかなどがよくわかりません。ヨロシクおねがいします! public class ExAnonymous11 { String s5="String5"; class B { String s2="String2"; A x = new A() { String s3="String3"; void m(final String s4){ System.out.println(s1); System.out.println(ExAnonymous11.B.this.s2); System.out.println(s3); System.out.println(s4); System.out.println(ExAnonymous11.this.s5); } }; void m2 (C x) { System.out.println(x.s6); System.out.println(x.m()); } void m () { x.m( "String4" ); final String s7 = "String7 "; m2( new C() { public String m() { return s7; } } ); } } void m () { B x = new B(); x.m(); } public static void main(String[] args) { ExAnonymous11 x = new ExAnonymous11(); x.m(); } } class A { String s1="String1"; void m(final String s4){} } interface C { String s6="String6"; public String m(); }

    • ベストアンサー
    • Java
  • List配列の検索

    インスタンス化されているJavaBeanがArrayListに数百~数千入っています。その配列から特定のJavaBeanのメンバーの内容が一致しているオブジェクトだけ取り出したいです。イテレーターを使って1個1個取り出してチェックして・・・というプログラムをゴリゴリ書いても良いのですが、SQLみたいに一致した条件のオブジェクトをまとめて取得するなんて事はできないのでしょうか? --- Goods.java --- import java.io.*; public class Goods implements Serializable{ private String name; private double price; private int stock; public Goods(){ } public Goods( String name, double price, int stock ){ this.name = name; this.price = price; this.stock = stock; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getStock() { return stock; } public void setStock(int stock) { this.stock = stock; } } というBeanがあり、仮に下記ロジックでaddし検索 --- mainlogic --- ArrayList<Goods> goodsList = new ArrayList<Goods>(); goodsList.add( new Goods("ABC",123,10) ); goodsList.add( new Goods("DEF",456, 0) ); // ←該当オブジェクト goodsList.add( new Goods("GHI",789,15) ); goodsList.add( new Goods("JKL",987, 0) ); // ←該当オブジェクト ・・・ // ここでgoodsListに入っているGoodsオブジェクトのメンバーstock(在庫数)が0のGoodsオブジェクトを取得したい ・・・ という感じなのですが、SQLなら"SELECT * FROM goodsList WHERE Goods.stock = 0"で簡単に抽出できるのですが、このような事ってできないですよね? やはり、イテレーターで全件検索か、一旦、オブジェクトをDBに書き出して取り出すという事しかできないですよね? 他に何か良い方法などありましたら、ご教授お願い致します。

  • MVCモデル設計(JSPでbeanからList))

    始めまして! いきなりですが、質問です。 MVCモデル設計でサーブレットからBeanのリストに値を格納し、BeanからJSPにそのリストの値を取得したいプログラムを作っているところなのですがリストから値を取得できません。。此方、javaに取り組み始めて一週間程です。 無駄な処理も多いと存じます。 とりあえずはJSPに値を持ってきて、ページに表示する。という形を作りたいです。 ご教授お願いします。 表示させるまでの勉強の仕方等も宜しければお願いします。 --jsp(syutok.jsp)-- <%@ page language="java" contentType="text/html; charset=Windows-31J" pageEncoding="Windows-31J"%> <%@ page import="java.util.*"%> <%@page import="java.util.List" import= "java.util.ArrayList"%> <jsp:useBean id="List" scope="page" class="expertBeans.Csvyomu"/> <%List<String> csv = new ArrayList<String>(); csv = List.getlist();%> <body> <table border="1" width="200" height="100" bgcolor="#9999ff"> <tr><td>車名</td><td>メーカー名</td><td>乗車人数</td><td>価格</td></tr> <tr><td><%=csv.get(0)%></td></tr> </table> --bean(Csvyomu)-- public class Csvyomu{ //車名 private String shamei; //メーカー private String mer; //乗車人数 private String zyonin; //価格 private String kakaku; //格納用beanlist List<String> kakunolist = new ArrayList<String>(); public void setshamei(String shamei){ this.shamei = shamei; kakunolist.add(shamei); System.out.println("ここに社名:"+shamei); } public String getshamei(){ return(shamei); } public void setmer(String mer){ this.mer = mer; kakunolist.add(mer); } public String getmer(){ return(mer); } public void setzyonin(String zyonin){ this.zyonin = zyonin; kakunolist.add(zyonin); } public String getzyonin(){ return(zyonin); } public void setkakaku(String kakaku){ this.kakaku = kakaku; kakunolist.add(kakaku); } public String getkakaku(){ return(kakaku); } public List<String> getlist(){ return (kakunolist); } } --サーブレット(yomukomi.java)-- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); request.setCharacterEncoding("Shift_JIS"); Csvyomu cs = new Csvyomu(); FileReader csvinput = null; BufferedReader csvread = null; List<String> datalist = new ArrayList<String>(); try{ csvinput = new FileReader("C:\\pleiades\\workspace\\kadai7_3\\csv\\CarInfo.csv"); csvread = new BufferedReader(csvinput); String csv; while((csv = csvread.readLine()) != null) { datalist.add(csv); String e = datalist.get(0); System.out.println(e); } } catch( FileNotFoundException erro ) { System.out.println(erro); } catch (IOException erro) { System.out.println(erro); } finally { try { if(csvread != null) { csvread.close(); } } catch (IOException erro ) { System.out.println(erro); } for( String csv2:datalist ){ String[] ary =csv2.split(",",0); cs.setshamei(ary[0]); cs.setmer(ary[1]); cs.setzyonin(ary[2]); cs.setkakaku(ary[3]); } } }

    • ベストアンサー
    • Java
  • Listに格納されているオブジェクトの照合(パターンマッチング?)

    2つのListオブジェクトを比較して、 それぞれの要素に格納されているクラスの属性が 一致しているかどうか、また、格納されている順番が同じかどうかを 調べたいのですが・・。 例えば、以下のようなかんじです↓ 1. 比較するListオブジェクト(1):userList //Userオブジェクト生成 User user1 = new User(); user1.setUserID(2); User user2 = new User(); user2.setUserID(4); //UserオブジェクトをListに格納 List userList = new ArrayList(); userList.add(user1); userList.add(user2); 2. 比較するListオブジェクト(2):specialUserList ※1.と同じ要領で生成されたもの List specialUserList; 3. 1と2を比較する 比較内容は以下の通りです。 1のListオブジェクト(userList)は、 1番目の要素に、 UserID:2 を持つUserオブジェクト 2番目の要素 に、UserID:4 を持つUserオブジェクト が格納されていますが、 2のListオブジェクト(specialUserList)も、 これと同じ構成で格納されているかどうか調べたいのです。 例えば、 2のListオブジェクトも、 1番目の要素に、 UserID:2 を持つUserオブジェクト 2番目の要素 に、UserID:4 を持つUserオブジェクト が格納されていればOKとし、上記以外であれば、NGとします。 例えば、以下のような内容がNGです。 1番目の要素に、 UserID:1(※2以外) を持つUserオブジェクト 2番目の要素 に、UserID:8(※4以外)を持つUserオブジェクト つまり、List要素に格納されている内容と、その格納されている順番が、 1と2で同じかどうかを調べたいのです。 もし分かる方いましたら、お力をお貸しください・・・

    • ベストアンサー
    • Java

専門家に質問してみよう