Tips

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

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

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

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

※この出題形式に関しては答えは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;
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 ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
	}
}

前回に引き続き、Userオブジェクトの定義を利用します。

toString, hashCode, equalsと実装してきましたので、Objectの関数としては、cloneを最後に実装したいと思います。

cloneをcommonsを利用して書き換えてください。

解答例1

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

[java] package jp.pjin.tech.commons.domain;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

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 ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}

@Override
public User clone() throws CloneNotSupportedException {
try {
return (User) BeanUtils.cloneBean(this);
} catch (IllegalAccessException | InstantiationException | InvocationTargetException
| NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
}
[/java]

BeanUtils#cloneBeanを利用します。
IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodExceptionをスローするので気を付けてください。
実行時例外がスローされた場合は、nullを返すように実装しています。

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

jp.pjin.tech.commons.Practice009.java

[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 Practice009 {
public static void main(String[] args) throws Exception {
User a = new User();
User b = new User();

System.out.println(a);
System.out.println(b);

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);
System.out.println(b);

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

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

User c = b.clone();
System.out.println(b + "@" + Integer.toHexString(b.hashCode()));
System.out.println(c + "@" + Integer.toHexString(c.hashCode()));

}
}
[/java]

hashCodeもついでに出力するようにしています。

Userオブジェクト、a, b を作成し、出力。
a, b に値を入れて、出力。
bのみ誕生日を変えて出力。この時にhashCodeが変わっていることに注目。
bをクローンしてcを作成し、出力。この時 b, c のhashCodeが同じことに注目。

実際のソースでありましたが、クローンではなく代入していて、cのオブジェクトに代入したら、bのオブジェクトまで変わっていたなんてことが、初心者にありがちです。
参照を渡しているだけなので、ちゃんとクローンしようよ~。

BeanUtilsにはcopyPropertiesという便利なメソッドが用意されています。
これを利用しても同様なことができます。

BeanUtilsはダウンロードしてください。

フィールドが多くなると、getter/setterだけでもサンプルで出すと多くなってしまいます。
大体のサイトは、getter/setterを省略しているのですが、これからは、Lombokを利用するようにします。

Eclipse:lombokインストール手順
Lombok 使い方メモ

ちなみにUserオブジェクトをLombokで書いてみると以下のようになります。

[java] package jp.pjin.tech.commons.domain;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;

import org.apache.commons.beanutils.BeanUtils;

import lombok.Data;

@Data
public class User implements Serializable {

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

@Override
public User clone() throws CloneNotSupportedException {
try {
return (User) BeanUtils.cloneBean(this);
} catch (IllegalAccessException | InstantiationException | InvocationTargetException
| NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
}
[/java]

hashCode, equals, toString は大体同様なものが作成されますのでオーバーライドしていません。
サンプルコードを利用すると同様な結果が出力されます。(toStringは少し見え方が異なります。)

@Dataアノテーションを付けるだけ!!なんてお手軽で、簡単に出来上がるのでしょうか。素晴らしい!!

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