at backyard

Color my life with the chaos of trouble.

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が重なるものだけが重複として除去されるよう。

ここらへんの処理の実装がうまくイメージできず、以前苦労した記憶がある。
自戒の念+自分の中でちゃんと整理してみたくて、ここに書いてみた。


なお、下記の記事を参考にさせていただいた。

qa.atmarkit.co.jp