Javaにて、List内のBeanが重複しているかを調べたい時
ArrayList内に格納したBeanの内容を比較して、
Beanの内容が重複している場合は、重複を除去したいとき、
Bean内にてequalsメソッドとhashCodeメソッドをOverrideすると、実行できるらしい。
public class UserBean01 { String id; String name; String mail; String pass; public UserBean01(String id, String name, String mail, String pass){ this.id = id; this.name = name; this.mail = mail; this.pass = pass; } // ************************ 各種変数のgetter&setter **************************// @Override public boolean equals(Object obj) { if (obj == null) return false; if (!(obj instanceof UserBean01)) return false; if (this == obj) return true; UserBean01 other = (UserBean01) obj; if (id == null && other.id != null || id != null && other.id == null) return false; if (name == null && other.name != null || name != null && other.name == null) return false; if (mail == null && other.mail != null || mail != null && other.mail == null) return false; if (pass == null && other.pass != null || pass != null && other.pass == null) return false; if (id.equals(other.id) && name.equals(name) && mail.equals(mail) && pass.equals(pass)) return true; return false; } @Override public int hashCode() { final int oddPrime = 31; int result = oddPrime; result += (id == null) ? 0 : id.hashCode(); result *= oddPrime; result += (name == null) ? 0 : name.hashCode(); result *= oddPrime; result += (mail == null) ? 0 : mail.hashCode(); result *= oddPrime; result += (pass == null) ? 0 : pass.hashCode(); return result; } }
こういうBeanを作成した場合、id, name,mail,passの内容が重複してるBeanを下記のようにして、除去出来る。
// UserBean01 test UserBean01 ub0101 = new UserBean01("1a", "test01","test01@example.com","test01"); UserBean01 ub0102 = new UserBean01("1b", "test02","test02@example.com","test02"); UserBean01 ub0103 = new UserBean01("1a", "test01","test01@example.com","test01"); Set<UserBean01> work = new LinkedHashSet<UserBean01>(); work.addAll(list); list.clear(); list.addAll(work); for(int i = 0; i < list.size(); i++){ System.out.println(list.get(i).getId()); }
ちなみに上記で作成したBeanを継承して、下記のようなBeanクラスを作成する。
equalsメソッドとhashCodeメソッドのOverrideする際の実装方法を変えることで、
重複とする条件を変えている。
public class UserBean02 extends UserBean01{ public UserBean02(String id, String name, String mail, String pass) { super(id, name, mail, pass); } @Override public boolean equals(Object obj) { if (obj == null) return false; if (!(obj instanceof UserBean02)) return false; if (this == obj) return true; UserBean02 other = (UserBean02) obj; if (id == null && other.id != null || id != null && other.id == null) return false; if (id.equals(id)) return true; return false; } @Override public int hashCode() { final int oddPrime = 31; int result = oddPrime; result += (id == null) ? 0 : id.hashCode(); return result; } }
idが被っていれば、重複しているという形にUserBean02クラスを定義した。
この継承したBeanを使用して、1つのプログラム内で重複の定義を二通り使用する。
下記の実装は一つのList内で、生成したBeanに応じて重複の定義を分け、
それぞれで重複となるBeanを除去している。
public class CompareTest { public static void main(String[] args){ // UserBean01 test UserBean01 ub0101 = new UserBean01("1a", "test01","test01@example.com","test01"); UserBean01 ub0102 = new UserBean01("1a", "test02","test02@example.com","test02"); UserBean01 ub0103 = new UserBean01("1a", "test01","test01@example.com","test01"); // UserBean02 Test UserBean01 ub0201 = new UserBean02("2a", "test01","test01@example.com","test01"); UserBean01 ub0202 = new UserBean02("2a", "test02","test02@example.com","test02"); UserBean01 ub0203 = new UserBean02("2a", "test03","test03@example.com","test03"); ArrayList<UserBean01> list = new ArrayList<UserBean01>(); list.add(ub0101); list.add(ub0102); list.add(ub0103); list.add(ub0201); list.add(ub0202); list.add(ub0203); Set<UserBean01> work = new LinkedHashSet<UserBean01>(); work.addAll(list); list.clear(); list.addAll(work); for(int i = 0; i < list.size(); i++){ System.out.println(list.get(i).getId()); } } }
この場合、UserBean01のub0101とub0103は重複するとされ、
UserBean02では、ub0201とub0202とub0203、全てが重複するとされ、
重複分は除去される。
この調子でUserBean02を継承したUserBean03を作成して、mailが重複しているものを"重複"と定義したうえで、
同じようにUserBean03のインスタンスを作成し、同じArrayList
UserBean03のインスタンス同士を比較し、mailが重なるものだけが重複として除去されるよう。
ここらへんの処理の実装がうまくイメージできず、以前苦労した記憶がある。
自戒の念+自分の中でちゃんと整理してみたくて、ここに書いてみた。
なお、下記の記事を参考にさせていただいた。