5月24日

前回は、以下のテストを書いたところで終了した。。

	@Test
	void ジュースを3種類管理できる() {
		VendingMachine vm = new VendingMachine();
		vm.put(100);
		boolean b = vm.canBuy("水");
		assertThat(b, is(true));
		b = vm.canBuy("コーラ");
		assertThat(b, is(false));
		b = vm.canBuy("レッドブル");
		assertThat(b, is(false));
	}

テストを実行してエラーになることを確認する。
水を購入できるか問い合わせたところでエラーが発生。

canBuy() メソッドでは、引数で名前をもらっているけど参照していなかった。
ジュースの名前を見て購入可能かを判断するように修正する。

	public boolean canBuy(String name) {
		if (juices.size() == 0) return false;
		return total >= getJuicePrice(name);
	}

getJuicePrice()にも引数を追加して、ジュースの名前を見て価格を返すようにする。

	public int getJuicePrice(String name) {
		if (name.equals("水")) return 100;
		if (name.equals("コーラ")) return 120;
		return 200;
	}

3種類のジュースを購入できるようにしたいので、水を購入するテストを追加する。

	@Test
	void ジュースを3種類購入する() {
		VendingMachine vm = new VendingMachine();
		vm.put(1000);
		Juice j = vm.buy("水");
		assertThat(j.getName(), is("水"));
	}

これまで、1種類(コーラ)しか売ってなかった自動販売機を複数に対応させるのは割と大変。
まずは3種類のジュースを在庫できるようにする。
Mapを追加して、ジュースの名前で在庫を取得できるようにする。

public class VendingMachine {
	private int total;
	private int sales;
	private Map<String, List<Juice>> map = new HashMap<>();
	private List<Juice> juices;

	public VendingMachine() {
		total = 0;
		juices = new ArrayList<>();
		map.put("水", juices);
		for (int i = 0; i < 5; i++) {
			juices.add(new Juice("水", 100));
		}
		juices = new ArrayList<>();
		map.put("コーラ", juices);
		for (int i = 0; i < 5; i++) {
			juices.add(new Juice("コーラ", 120));
		}
		juices = new ArrayList<>();
		map.put("レッドブル", juices);
		for (int i = 0; i < 5; i++) {
			juices.add(new Juice("レッドブル", 200));
		}
	}

テストを実行すると、これまで動いていたテスト「ジュースを購入する()」などでエラーになる。
これはジュースの名前を見ていないのが原因。
ジュースの名前を見て、Mapから在庫を取得するように変更する。

	public Juice buy(String name) {
		if (!canBuy(name)) return null;
		juices = map.get(name);
		Juice j = juices.remove(0);
		total -= j.getPrice();
		sales += j.getPrice();
		return j;
	}

3種類のジュースを購入するテストを書く。

	@Test
	void ジュースを3種類購入する() {
		VendingMachine vm = new VendingMachine();
		vm.put(1000);
		Juice j = vm.buy("水");
		assertThat(j.getName(), is("水"));
		int total = vm.getTotal();
		assertThat(total, is(900));
		int stock = vm.getJuiceStock("水");
		assertThat(stock, is(4));

		j = vm.buy("レッドブル");
		assertThat(j.getName(), is("レッドブル"));
		total = vm.getTotal();
		assertThat(total, is(700));

		j = vm.buy("コーラ");
		assertThat(j.getName(), is("コーラ"));
		total = vm.getTotal();
		assertThat(total, is(580));

		int sales = vm.getSales();
		assertThat(sales, is(420));
	}

getJuiceStock() に引数を追加して、ジュースの名前を指定して在庫を取得できるようにする。

	public int getJuiceStock(String name) {
		return juices.size();
	}

ジュースの名前を見てないのに、getJuiceStock() のテストをパスしているので、怪しい実装を修正するためにテストを追加する。

	@Test
	void ジュースを3種類購入する() {
		VendingMachine vm = new VendingMachine();
		vm.put(1000);
		Juice j = vm.buy("水");
		assertThat(j.getName(), is("水"));
		int total = vm.getTotal();
		assertThat(total, is(900));
		int stock = vm.getJuiceStock("水");
		assertThat(stock, is(4));
		stock = vm.getJuiceStock("レッドブル");
		assertThat(stock, is(5));

		j = vm.buy("レッドブル");
		assertThat(j.getName(), is("レッドブル"));
		total = vm.getTotal();
		assertThat(total, is(700));

		j = vm.buy("コーラ");
		assertThat(j.getName(), is("コーラ"));
		total = vm.getTotal();
		assertThat(total, is(580));

		int sales = vm.getSales();
		assertThat(sales, is(420));
	}

このテストで、レッドブルの在庫数を正しく返せてないことがわかる。
getJuiceStocck() をきちんと実装しなおす。

	public int getJuiceStock(String name) {
		juices = map.get(name);
		return juices.size();
	}

購入可能なドリンクのリストを知りたい!
テストを作成する。

	@Test
	void 購入可能なドリンクのリスト() {
		VendingMachine vm = new VendingMachine();
		Juice[] list = vm.getBuyableJuices();
		assertThat(list.length, is(0));
	}

コンパイルエラーを解消する。
VendingMachine に以下のメソッドを追加する。

	public Juice[] getBuyableJuices() {
		return null;
	}

テストには失敗するので、テストにパスするように実装する。
とりあえず fake で。

	public Juice[] getBuyableJuices() {
		return new Juice[0];
	}

テストを追加する。
100円を投入すると水を購入できる。

	@Test
	void 購入可能なドリンクのリスト() {
		VendingMachine vm = new VendingMachine();
		Juice[] list = vm.getBuyableJuices();
		assertThat(list.length, is(0));
		vm.put(100);
		list = vm.getBuyableJuices();
		assertThat(list.length, is(1));
		assertThat(list[0].getName(), is("水"));
	}

100円を追加投入すると3種類のドリンクを購入できる。

	@Test
	void 購入可能なドリンクのリスト() {
		VendingMachine vm = new VendingMachine();
		Juice[] list = vm.getBuyableJuices();
		assertThat(list.length, is(0));
		vm.put(100);
		list = vm.getBuyableJuices();
		assertThat(list.length, is(1));
		assertThat(list[0].getName(), is("水"));
		vm.put(100);
		list = vm.getBuyableJuices();
		assertThat(list.length, is(3));
	}

手抜きの実装でテストをパスさせる。

	public Juice[] getBuyableJuices() {
		if (total >= 200) {
			Juice[] list = {
					new Juice("水", 100),
					new Juice("コーラ", 120),
					new Juice("レッドブル", 200)
				};
			return list;
		}
		if (total >= 120) {
			Juice[] list = {
					new Juice("水", 100),
					new Juice("コーラ", 120),
				};
			return list;

		}
		if (total >= 100) {
			Juice[] list = {
					new Juice("水", 100),
				};
			return list;

		}
		return new Juice[0];
	}

在庫がなくなったらリストに出ないテストを作成する。
合計700円を投入して水を5個買うと、200円残る。
水の在庫がなくなったので、リストはコーラとレッドブルの2個だけになる。

	@Test
	void 購入可能なドリンクのリスト() {
		VendingMachine vm = new VendingMachine();
		Juice[] list = vm.getBuyableJuices();
		assertThat(list.length, is(0));
		vm.put(100);
		list = vm.getBuyableJuices();
		assertThat(list.length, is(1));
		assertThat(list[0].getName(), is("水"));
		vm.put(100);
		list = vm.getBuyableJuices();
		assertThat(list.length, is(3));
		vm.put(500);
		for (int i = 0; i < 5; i++) {
			Juice j = vm.buy("水");
			assertThat(j.getName(), is("水"));
		}
		list = vm.getBuyableJuices();
		assertThat(list.length, is(2));
	}
	public Juice[] getBuyableJuices() {
		Collection<List<Juice>> c = map.values();
		List<Juice> list = new ArrayList<>();
		for (List<Juice> l : c) {
			if (l.size() == 0) continue;
			Juice j = l.get(0);
			if (j.getPrice() > total) continue;
			list.add(j);
		}
		return list.toArray(new Juice[0]);
	}

5月21日

前回は返金するテストを作ったところで終わっていたので、まずはテストを実行してみる。
すると、返金するテストでエラーになるので、そこから作業を再開すればいいことがわかる。

返金を実装する。

	public int refund() {
		int refund = total;
		total = 0;
		return refund;
	}

扱えないお金

テストを書く。

	@Test
	void 投入できないお金() {
		VendingMachine vm = new VendingMachine();
		vm.put(1);
		int total = vm.getTotal();
		assertThat(total, is(0));
		vm.put(5);
		total = vm.getTotal();
		assertThat(total, is(0));
		vm.put(20);
		total = vm.getTotal();
		assertThat(total, is(0));
		vm.put(5000);
		total = vm.getTotal();
		assertThat(total, is(0));
	}

10円・50円・100円・500円・1000円だけ受け付けるようにすればよい。

	public void put(int i) {
		// 10円・50円・100円・500円・1000円だけ受け付ける
		if (i == 10 ||
			i == 50 ||
			i == 100 ||
			i == 500 ||
			i == 1000) {
			total += i;
		}
	}

ジュースの管理

テストを書く。

	@Test
	void ジュースを格納できる() {
		VendingMachine vm = new VendingMachine();
		String name = vm.getJuiceName();
		assertThat(name, is("コーラ"));
		int price = vm.getJuicePrice();
		assertThat(price, is(120));
		int stock = vm.getJuiceStock();
		assertThat(stock, is(5));
	}

このテストに関しては、fakeだけでテストにパスできる。

	public String getJuiceName() {
		return "コーラ";
	}

	public int getJuicePrice() {
		return 120;
	}

	public int getJuiceStock() {
		return 5;
	}

ジュースを購入する。

テストを書く。

	@Test
	void ジュースを購入する() {
		VendingMachine vm = new VendingMachine();
		boolean b = vm.canBuy("コーラ");
		assertThat(b, is(false));
		vm.put(500);
		b = vm.canBuy("コーラ");
		assertThat(b, is(true));
	}

テストにパスするように自動販売機を実装する。

	public boolean canBuy(String name) {
		return total >= getJuicePrice();
	}

購入できるようにする。

	@Test
	void ジュースを購入する() {
		VendingMachine vm = new VendingMachine();
		boolean b = vm.canBuy("コーラ");
		assertThat(b, is(false));
		vm.put(500);
		b = vm.canBuy("コーラ");
		assertThat(b, is(true));
		Juice juice = vm.buy("コーラ");

Juiceがないので新規にクラスを作成する。

package jp.abc;

public class Juice {
	private String name;
	private int price;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}
}

Juiceを作ったので、テストの続きを作成する。

	@Test
	void ジュースを購入する() {
		VendingMachine vm = new VendingMachine();
		boolean b = vm.canBuy("コーラ");
		assertThat(b, is(false));
		vm.put(500);
		b = vm.canBuy("コーラ");
		assertThat(b, is(true));
		Juice juice = vm.buy("コーラ");
		assertThat(juice.getName(), is("コーラ"));
	}

テストではジュースの名前だけチェックしているのでfakeで実装しておく。

	public Juice buy(String name) {
		Juice j = new Juice();
		j.setName("コーラ");
		return j;
	}

ジュースを購入すると在庫を減らさないといけないのでテストを追加する。

	@Test
	void ジュースを購入する() {
		VendingMachine vm = new VendingMachine();
		boolean b = vm.canBuy("コーラ");
		assertThat(b, is(false));
		vm.put(500);
		b = vm.canBuy("コーラ");
		assertThat(b, is(true));
		Juice juice = vm.buy("コーラ");
		assertThat(juice.getName(), is("コーラ"));
		int stock = vm.getJuiceStock();
		assertThat(stock, is(4));
	}

テストをパスするようにまじめに実装する。
Juiceクラスには、引数付きコンストラクタが欲しいので追加しておく。
既存のコードで引数なしのコンストラクタを使っているので引数なしのコンストラクタも定義しておく。

	public Juice(String name, int price) {
		this.name = name;
		this.price = price;
	}
	public Juice() {
		this("", 0);
	}
package jp.abc;

import java.util.ArrayList;
import java.util.List;

public class VendingMachine {
	private int total;
	private List<Juice> juices = new ArrayList<>();

	public VendingMachine() {
		total = 0;
		for (int i = 0; i < 5; i++) {
			juices.add(new Juice("コーラ", 120));
		}
	}

	public void put(int i) {
		// 10円・50円・100円・500円・1000円だけ受け付ける
		if (i == 10 ||
			i == 50 ||
			i == 100 ||
			i == 500 ||
			i == 1000) {
			total += i;
		}
	}

	public int getTotal() {
		return total;
	}

	public int refund() {
		int refund = total;
		total = 0;
		return refund;
	}

	public String getJuiceName() {
		return "コーラ";
	}

	public int getJuicePrice() {
		return 120;
	}

	public int getJuiceStock() {
		return juices.size();
	}

	public boolean canBuy(String name) {
		return total >= getJuicePrice();
	}

	public Juice buy(String name) {
		Juice j = juices.remove(0);
		return j;
	}
}

ジュースを購入すると合計金額が減るのをテストに追加する。

	@Test
	void ジュースを購入する() {
		VendingMachine vm = new VendingMachine();
		boolean b = vm.canBuy("コーラ");
		assertThat(b, is(false));
		vm.put(500);
		b = vm.canBuy("コーラ");
		assertThat(b, is(true));
		Juice juice = vm.buy("コーラ");
		assertThat(juice.getName(), is("コーラ"));
		int stock = vm.getJuiceStock();
		assertThat(stock, is(4));
		int total = vm.getTotal();
		assertThat(total, is(380));
	}

テストにパスするように実装する。

	public Juice buy(String name) {
		Juice j = juices.remove(0);
		total -= j.getPrice();
		return j;
	}

投入金額が足りないときはジュースを購入できないテストを追加する。

	@Test
	void 金額不足でジュースを購入できない() {
		VendingMachine vm = new VendingMachine();
		Juice j = vm.buy("コーラ");
		assertThat(j, is(nullValue()));
	}

テストにパスするように実装する。

	public Juice buy(String name) {
		if (!canBuy(name)) return null;
		Juice j = juices.remove(0);
		total -= j.getPrice();
		return j;
	}

在庫がないときはジュースを購入できないテストを追加する。

	@Test
	void 在庫がないのでジュースを購入できない() {
		VendingMachine vm = new VendingMachine();
		vm.put(1000);
		for (int i = 0; i < 5; i++) {
			Juice j = vm.buy("コーラ");
			assertThat(j.getName(), is("コーラ"));
		}
		Juice j = vm.buy("コーラ");
		assertThat(j, is(nullValue()));
	}

テストにパスするように実装する。
在庫が0なので購入できない。

	public boolean canBuy(String name) {
		if (juices.size() == 0) return false;
		return total >= getJuicePrice();
	}

売上金額を取得できるようにする。
まずはテストを作成する。

	@Test
	void 現在の売上金額を取得できる() {
		VendingMachine vm = new VendingMachine();
		int sales = vm.getSales();
		assertThat(sales, is(0));
		vm.put(1000);
		Juice j = vm.buy("コーラ");
		sales = vm.getSales();
		assertThat(sales, is(120));
	}

テストにパスするように実装する。

package jp.abc;

import java.util.ArrayList;
import java.util.List;

public class VendingMachine {
	private int total;
	private int sales;
	private List<Juice> juices = new ArrayList<>();

	public VendingMachine() {
		total = 0;
		for (int i = 0; i < 5; i++) {
			juices.add(new Juice("コーラ", 120));
		}
	}

	public void put(int i) {
		// 10円・50円・100円・500円・1000円だけ受け付ける
		if (i == 10 ||
			i == 50 ||
			i == 100 ||
			i == 500 ||
			i == 1000) {
			total += i;
		}
	}

	public int getTotal() {
		return total;
	}

	public int refund() {
		int refund = total;
		total = 0;
		return refund;
	}

	public String getJuiceName() {
		return "コーラ";
	}

	public int getJuicePrice() {
		return 120;
	}

	public int getJuiceStock() {
		return juices.size();
	}

	public boolean canBuy(String name) {
		if (juices.size() == 0) return false;
		return total >= getJuicePrice();
	}

	public Juice buy(String name) {
		if (!canBuy(name)) return null;
		Juice j = juices.remove(0);
		total -= j.getPrice();
		sales += j.getPrice();
		return j;
	}

	public int getSales() {
		return sales;
	}
}

返金操作で釣銭を返すテストを作成する。

	@Test
	void 返金操作で釣銭を返す() {
		VendingMachine vm = new VendingMachine();
		vm.put(1000);
		Juice j = vm.buy("コーラ");
		int refund = vm.refund();
		assertThat(refund, is(880));
	}

何も実装しないでもテストにパスした!!!!!!!

機能拡張する。

ジュースを3種類管理できるようにする。

	@Test
	void ジュースを3種類管理できる() {
		VendingMachine vm = new VendingMachine();
		vm.put(100);
		boolean b = vm.canBuy("水");
		assertThat(b, is(true));
		b = vm.canBuy("コーラ");
		assertThat(b, is(false));
		b = vm.canBuy("レッドブル");
		assertThat(b, is(false));
	}

5月7日

授業の内容を記録するブログ
URL: http://2019se3.satoshis.jp/

テキストの14章から

リスト14-1

package ex;

public class Main {

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		// ここで何らかの時間がかかる処理
		long end = System.currentTimeMillis();
		System.out.println("処理にかかった時間は…"
				+ (end - start) + "ミリ秒でした");
	}

}

前回の素数かどうかを判定するためのJUnitテスト PrimeTest.java

package ex;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import org.junit.jupiter.api.Test;

class PrimeTest {

	@Test
	void 素数() {
		Prime p = new Prime();
		assertThat(p.isPrime(2), is(true));
		assertThat(p.isPrime(3), is(true));
		assertThat(p.isPrime(5), is(true));
		assertThat(p.isPrime(7), is(true));
		assertThat(p.isPrime(11), is(true));
		assertThat(p.isPrime(13), is(true));
		assertThat(p.isPrime(6700417), is(true));
		assertThat(p.isPrime(Integer.MAX_VALUE), is(true));
		//System.out.println(Integer.MAX_VALUE);
	}

	@Test
	void 素数ではない() {
		Prime p = new Prime();
		assertThat(p.isPrime(4), is(false));
		assertThat(p.isPrime(6), is(false));
		assertThat(p.isPrime(8), is(false));
		assertThat(p.isPrime(9), is(false));
	}
}

ターゲットプログラム Prime.java

package ex;

public class Prime {

	public boolean isPrime(int n) {
		if (n == 2) return true;
		if (n % 2 == 0) return false;
		for (int i = 3; i < n /2; i+=2) {
			if (n % i == 0) return false;
		}
		return true;
	}

}

この素数判定をリスト14-1の時間がかかる処理として追加する。

package ex;

public class Main {

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		// ここで何らかの時間がかかる処理
		Prime p = new Prime();
		boolean b = p.isPrime(Integer.MAX_VALUE);
		System.out.println(Integer.MAX_VALUE
				+ "の素数判定結果は" + b + "です");
		long end = System.currentTimeMillis();
		System.out.println("処理にかかった時間は…"
				+ (end - start) + "ミリ秒でした");
	}

}

実行結果は以下の通り。

2147483647の素数判定結果はtrueです
処理にかかった時間は…1148ミリ秒でした

テキストのリスト14-2のコードを追加する。

package ex;

import java.util.Date;

public class Main {

	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		// ここで何らかの時間がかかる処理
		Prime p = new Prime();
		boolean b = p.isPrime(Integer.MAX_VALUE);
		System.out.println(Integer.MAX_VALUE
				+ "の素数判定結果は" + b + "です");
		long end = System.currentTimeMillis();
		System.out.println("処理にかかった時間は…"
				+ (end - start) + "ミリ秒でした");

		// リスト14-2
		Date now = new Date();
		System.out.println(now);
		System.out.println(now.getTime());
		Date past = new Date(1316622225935L);
		System.out.println(past);
	}

}

実行結果は以下の通り。

2147483647の素数判定結果はtrueです
処理にかかった時間は…1142ミリ秒でした
Tue May 07 10:34:32 JST 2019
1557192872306
Thu Sep 22 01:23:45 JST 2011

テキストのリスト14-3をCalMain.javaとして作成する。

package ex;

import java.util.Calendar;
import java.util.Date;

public class CalMain {

	public static void main(String[] args) {
		// 現在の年を表示する
		Date now = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(now);
		int y = c.get(Calendar.YEAR);
		System.out.println("今年は" + y + "年です");
		// 指定した日のDate型の値を得る
		c.set(2010, 8, 22, 1, 23, 45);
		Date past = c.getTime();
		System.out.println(past);
	}

}

SimpleDateFormat の使用例としてリスト14-4 のコードをCalMain.javaに追加する。

package ex;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CalMain {

	public static void main(String[] args) throws Exception {
		// 現在の年を表示する
		Date now = new Date();
		Calendar c = Calendar.getInstance();
		c.setTime(now);
		int y = c.get(Calendar.YEAR);
		System.out.println("今年は" + y + "年です");
		// 指定した日のDate型の値を得る
		c.set(2010, 8, 22, 1, 23, 45);
		Date past = c.getTime();
		System.out.println(past);

		// リスト14-4 のコードを追加
		SimpleDateFormat f =
				new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		String s = f.format(now);
		System.out.println(s);
		// 指定日時の文字列を解析しDate型として得る
		Date d = f.parse("2011/09/22 01:23:45");
		System.out.println(d);
	}

}

リスト14-5 Empty.java

package ex;

public class Empty {

}

EmptyMain.java (テキストでは Main.java)

package ex;

public class EmptyMain {

	public static void main(String[] args) {
		Empty e = new Empty();
		String s = e.toString();
		System.out.println(s);
	}

}

実行結果は以下の通り。
@の手前はFQCNで@のあとはハッシュ値の16進数表記。

ex.Empty@70dea4e

toString() メソッドのカスタマイズ
Heroクラスを選択した状態で、メニューから[ソース]-[toString()生成]を選択する。
そのままOKすると、EclipseがtoString()メソッドを生成してくれる。
toString()で表示する必要がないフィールドがあれば、チェックを外してからOKする。

Hero.java

package ex;

public class Hero {
	String name;
	int hp;

	@Override
	public String toString() {
		return getClass().getName()
				+ "[name=" + name + ", hp=" + hp + "]";
	}
}

HeroMain.java

package ex;

public class HeroMain {

	public static void main(String[] args) {
		Hero h = new Hero();
		h.name = "ミナト";
		h.hp = 100;
		System.out.println(h.toString());
	}

}

Heroクラスを比較するために equals() メソッドを使ってみる。

package ex;

public class HeroMain {

	public static void main(String[] args) {
		Hero h = new Hero();
		h.name = "ミナト";
		h.hp = 100;
		System.out.println(h.toString());
		Hero h2 = new Hero();
		h2.name = "ミナト";
		h2.hp = 100;
		System.out.println(h.equals(h2));
	}

}

実行結果は以下の通り。

ex.Hero[name=ミナト, hp=100]
false

名前とhpが同じならtrueにしたい。

Eclipseに equals() メソッドを生成する機能があるので、それを使うと便利。
Heroクラスを選択した状態でメニューから[ソース]-[hashCode()およびequals()の生成]を選択する。
hpとnameフィールドにチェックが入っているのを確認してOKする。
すると、hashCode()とequals()メソッドが生成される。
HeroMainを実行すると、trueが出力されるのが確認できる。

package ex;

public class Hero {
	String name;
	int hp;

	@Override
	public String toString() {
		return getClass().getName()
				+ "[name=" + name + ", hp=" + hp + "]";
	}

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

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Hero other = (Hero) obj;
		if (hp != other.hp)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
}

HeroMainでh2の名前とHPを変更して、きちんと判定しているか確認する。

package ex;

public class HeroMain {

	public static void main(String[] args) {
		Hero h = new Hero();
		h.name = "ミナト";
		h.hp = 100;
		System.out.println(h.toString());
		Hero h2 = new Hero();
		h2.name = "ミナト";
		h2.hp = 100;
		System.out.println(h.equals(h2));
		h2.hp = 101;
		System.out.println(h.equals(h2));
		h2.hp = 100;
		System.out.println(h.equals(h2));
		h2.name = "ミナトA";
		System.out.println(h.equals(h2));
	}

}

実行結果は以下の通り。

ex.Hero[name=ミナト, hp=100]
true
false
true
false

コレクションフレームワーク
コレクションフレームワークは、複数のオブジェクトを扱う仕組みで、Javaではjava.utilパッケージにインタフェースやクラスが用意されている。

Listインタフェースの実装であるArrayListを使用した例。
add() : 要素を追加する。
remove() : 要素を削除する。
size() : 要素の数。
contains() : 要素が含まれているかどうかを調べる。

package ex;

import java.util.ArrayList;

public class ListMain {

	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<>();
		list.add("プレミアムモルツ");
		list.add("バドワイザー");
		list.add("ギネス");
		//System.out.println(list.get(1));
		list.add(0, "一番搾り");
		//System.out.println(list.get(1));
		// ループで要素を表示
		for (int i = 0; i < list.size(); i++) {
			System.out.println(i + ":" + list.get(i));
		}
		list.remove(0);
		for (String s : list) {
			System.out.println(s);
		}
		System.out.println(list.contains("一番搾り"));
		list.remove("ギネス");
		for (String s : list) {
			System.out.println(s);
		}
	}

}

Setインタフェースを実装したHashSetを使用した例。

package ex;

import java.util.HashSet;
import java.util.Set;

public class SetMain {

	public static void main(String[] args) {
		Set<String> set = new HashSet<>();
		set.add("マリオ");
		set.add("ルイージ");
		set.add("ピーチ");
		for (String s : set) {
			System.out.println(s);
		}
		set.add("マリオ");
		for (String s : set) {
			System.out.println(s);
		}
		System.out.println(set.contains("ピーチ"));
		set.remove("ピーチ");
		for (String s : set) {
			System.out.println(s);
		}
		System.out.println(set.contains("ピーチ"));
	}

}

実行結果は以下の通り。

マリオ
ピーチ
ルイージ
マリオ
ピーチ
ルイージ
true
マリオ
ルイージ
false

Mapインタフェースを実装したHashMapを使用した例。

package ex;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapMain {

	public static void main(String[] args) {
		Map<String, String> map = new HashMap<>();
		map.put("m", "モンスターハンター");
		map.put("d", "ドラゴンクエスト");
		map.put("p", "ポケットモンスター");
		System.out.println(map.get("m"));
		Set<String> set = map.keySet();
		for (String key : set) {
			String v = map.get(key);
			System.out.println(key + ":" + v);
		}
		System.out.println(map.containsKey("a"));
		map.put("p", "パズルアンドドラゴンズ");
		for (String key : set) {
			String v = map.get(key);
			System.out.println(key + ":" + v);
		}
	}

}

実行結果は以下の通り。

モンスターハンター
p:ポケットモンスター
d:ドラゴンクエスト
m:モンスターハンター
false
p:パズルアンドドラゴンズ
d:ドラゴンクエスト
m:モンスターハンター