Tips

Apache Commons Javaプログラム演習問題 第7回

Apache Commons Javaプログラム演習問題 第7回

Apache Commons を利用した Java でのプログラム作成問題の7回目となります。

環境を構築していない場合は、概要を読み、環境を構築してから実施してください。

※この出題形式に関しては答えは1つではありません。
解答例はできるだけ複数載せるつもりですが、問題文の要件を満たしていれば正解として下さい。

問題

jp.pjin.tech.commons.domain.BloodType.java

package jp.pjin.tech.commons.domain;

public enum BloodType {
	A, B, O, AB
}

jp.pjin.tech.commons.domain.User.java

package jp.pjin.tech.commons.domain;

import java.io.Serializable;
import java.time.LocalDate;

import org.apache.commons.lang3.builder.EqualsBuilder;

public class User implements Serializable {

	private int id;
	private String name;
	private BloodType type;
	private LocalDate birthday;
	private String mail;
	private String phone;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public BloodType getType() {
		return type;
	}

	public void setType(BloodType type) {
		this.type = type;
	}

	public LocalDate getBirthday() {
		return birthday;
	}

	public void setBirthday(LocalDate birthday) {
		this.birthday = birthday;
	}

	public String getMail() {
		return mail;
	}

	public void setMail(String mail) {
		this.mail = mail;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((birthday == null) ? 0 : birthday.hashCode());
		result = prime * result + id;
		result = prime * result + ((mail == null) ? 0 : mail.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((phone == null) ? 0 : phone.hashCode());
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		return EqualsBuilder.reflectionEquals(this, obj);
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", type=" + type + ", birthday=" + birthday + ", mail=" + mail
				+ ", phone=" + phone + "]";
	}
}

前回に引き続き、Userオブジェクトの定義を利用します。
#hashCode は eclipseにて自動生成したものです。

Classを右クリックし、「ソース」から「hashCode()およびequals()の生成」を実行しました。

自動生成された、hashCodeをcommonsを利用して書き換えてください。

解答例1

jp.pjin.tech.commons.domain.User.java

package jp.pjin.tech.commons.domain;

import java.io.Serializable;
import java.time.LocalDate;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

public class User implements Serializable {

	private int id;
	private String name;
	private BloodType type;
	private LocalDate birthday;
	private String mail;
	private String phone;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public BloodType getType() {
		return type;
	}

	public void setType(BloodType type) {
		this.type = type;
	}

	public LocalDate getBirthday() {
		return birthday;
	}

	public void setBirthday(LocalDate birthday) {
		this.birthday = birthday;
	}

	public String getMail() {
		return mail;
	}

	public void setMail(String mail) {
		this.mail = mail;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	@Override
	public int hashCode() {
		return HashCodeBuilder.reflectionHashCode(this);
	}

	@Override
	public boolean equals(Object obj) {
		return EqualsBuilder.reflectionEquals(this, obj);
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", type=" + type + ", birthday=" + birthday + ", mail=" + mail
				+ ", phone=" + phone + "]";
	}
}

すっきりしたのではないでしょうか。
HashCodeBuilder#reflectionHashCodeを利用します。

実際ちゃんと比較できるか確認してみましょう。

jp.pjin.tech.commons.Practice007.java

package jp.pjin.tech.commons;

import java.time.LocalDate;

import jp.pjin.tech.commons.domain.BloodType;
import jp.pjin.tech.commons.domain.User;

public class Practice007 {
	public static void main(String[] args) {
		User a = new User();
		User b = new User();

		System.out.println("a:" + Integer.toHexString(a.hashCode()));
		System.out.println("b:" + Integer.toHexString(b.hashCode()));

		a.setId(10);
		b.setId(10);

		a.setName("山田太郎");
		b.setName("山田太郎");

		a.setType(BloodType.A);
		b.setType(BloodType.A);

		a.setBirthday(LocalDate.of(2019, 1, 1));
		b.setBirthday(LocalDate.of(2019, 1, 1));

		a.setMail("yamada@ssie.jp");
		b.setMail("yamada@ssie.jp");

		a.setPhone("000-0000-0000");
		b.setPhone("000-0000-0000");

		System.out.println("a:" + Integer.toHexString(a.hashCode()));
		System.out.println("b:" + Integer.toHexString(b.hashCode()));

		b.setBirthday(LocalDate.of(2019, 2, 26));

		System.out.println("a:" + Integer.toHexString(a.hashCode()));
		System.out.println("b:" + Integer.toHexString(b.hashCode()));
	}
}

上記プログラムを実行すると、a, b のそれぞれのHashCodeが出力されます。
bの部分のみ変更した後に、hashCodeを出力すると、別の数字が出力されるのが分かります。

javadoc Object#hashCodeで定義されているhashCodeの一般的な規則は以下です。

hashCode の一般的な規則は次のとおりです。

  • Java アプリケーションの実行中に同じオブジェクトに対して複数回呼び出された場合は常に、このオブジェクトに対する equals の比較で使用される情報が変更されていなければ、hashCode メソッドは常に同じ整数を返す必要があります。ただし、この整数は同じアプリケーションの実行ごとに同じである必要はありません。
  • equals(Object) メソッドに従って 2 つのオブジェクトが等しい場合は、2 つの各オブジェクトに対する hashCode メソッドの呼び出しによって同じ整数の結果が生成される必要があります。
  • equals(java.lang.Object) メソッドに従って 2 つのオブジェクトが等しくない場合は、2 つの各オブジェクトに対する hashCode メソッドの呼び出しによって異なる整数の結果が生成される必要はありません。ただし、プログラマは、等しくないオブジェクトに対して異なる整数の結果を生成すると、ハッシュテーブルのパフォーマンスが向上する場合があることに気付くはずです。

クラス Object によって定義された hashCode メソッドは、可能なかぎり、異なるオブジェクトに対して異なる整数を返します。(これは通常、オブジェクトの内部アドレスを整数に変換することによって実装されますが、この実装テクニックは JavaTM プログラミング言語では必要ありません。)

apache commons

Apache Commons Javaプログラム演習問題 第23回

Apache Commons を利用した Java でのプログラム作成問題の23回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 ※この出題形式に関しては答えは1つではありません。 解答例はできるだけ複数載せるつもりですが、問題文の要件を満たしていれば正
apache commons

Apache Commons Javaプログラム演習問題 第22回

Apache Commons を利用した Java でのプログラム作成問題の22回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 ※この出題形式に関しては答えは1つではありません。 解答例はできるだけ複数載せるつもりですが、問題文の要件を満たしていれば正
apache commons

Apache Commons Javaプログラム演習問題 第21回

Apache Commons を利用した Java でのプログラム作成問題の21回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 ※この出題形式に関しては答えは1つではありません。 解答例はできるだけ複数載せるつもりですが、問題文の要件を満たしていれば正
apache commons

Apache Commons Javaプログラム演習問題 第20回

Apache Commons を利用した Java でのプログラム作成問題の20回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 ※この出題形式に関しては答えは1つではありません。 解答例はできるだけ複数載せるつもりですが、問題文の要件を満たしていれば正
apache commons

Apache Commons Javaプログラム演習問題 第19回

Apache Commons を利用した Java でのプログラム作成問題の19回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 DB環境の準備は、Apache Commons Javaプログラム演習問題 第16回をご覧ください。 ※この出題形式に関して
apache commons

Apache Commons Javaプログラム演習問題 第18回

Apache Commons を利用した Java でのプログラム作成問題の18回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 DB環境の準備は、Apache Commons Javaプログラム演習問題 第16回をご覧ください。 ※この出題形式に関して
apache commons

Apache Commons Javaプログラム演習問題 第17回

Apache Commons を利用した Java でのプログラム作成問題の17回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 DB環境の準備は、Apache Commons Javaプログラム演習問題 第16回をご覧ください。 ※この出題形式に関して
apache commons

Apache Commons Javaプログラム演習問題 第16回

Apache Commons を利用した Java でのプログラム作成問題の16回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 ※この出題形式に関しては答えは1つではありません。 解答例はできるだけ複数載せるつもりですが、問題文の要件を満たしていれば正
apache commons

Apache Commons Javaプログラム演習問題 第12回

Apache Commons を利用した Java でのプログラム作成問題の12回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 ※この出題形式に関しては答えは1つではありません。 解答例はできるだけ複数載せるつもりですが、問題文の要件を満たしていれば正
apache commons

Apache Commons Javaプログラム演習問題 第15回

Apache Commons を利用した Java でのプログラム作成問題の15回目となります。 環境を構築していない場合は、概要を読み、環境を構築してから実施してください。 ※この出題形式に関しては答えは1つではありません。 解答例はできるだけ複数載せるつもりですが、問題文の要件を満たしていれば正

新連載はじまりました!新Java基礎 連載リンク

はじめてのJAVA 連載

Recent News

Recent Tips

Tag Search