😽

【Java】Mapについて

2023/12/06に公開

概要

Mapについて、解説する。Mapとは、キーと値のペアを使用するデータ構造で、マップ内のアイテムを検索する際、アイテム数が増えても検索時間が一定となる。Mapの利点を理解するには、リストや配列内でアイテムを探す場合を想像するといい。

例えば、あるリストに10個のアイテムがある場合、見つけたいアイテムを探す時には、最悪のケースでは10個全てチェックする必要がある。1000個であれば、1000個チェックするかもしれない。つまり、アイテムを見つけるのにかかる時間が、リストのアイテム数に比例して増加する。

対照的に、マップはキーと値をペアとして持っているので、単純にキーを提供すれば、探している値が見つけられる。そのため、マップ内のアイテム数に関係なく、同じ時間がかかるため、検索時間は一定である。つまり、マップに追加されるアイテム数が増えても変わらない。

例えるのであれば、大きな図書館の中で特定の本を探すときに、IDがなくて本を一つずつチェックしなければいけないのか、もしくは本にユニークなIDがあって、それを使ってすぐ本を探せるか、といった違いである。

ハンズオン

mapsExample.java

こちらのファイルでは、名前とemailを格納するクラスを作っている。

public class Person {

	private final String name;
	private final String email;

	public Person(String name, String email) {
		this.name = name;
		this.email = email;
	}

	public String getName() {
		return name;
	}

	public String getEmail() {
		return email;
	}

	@Override
	public String toString() {
		return name + " " + email;
	}

}

MapExercise

まず、mapOfPeopleという名前とemailを格納するためのmapを作っている。

public class MapExcercise {

	public static void main(String[] args) {

		Map<String, Person> mapOfPeople = new HashMap<String, Person>();

次に、mike, shaun, sally, cesarというキーと値を作って、それらを配列に格納している。

		Person mike = new Person("Mike", "mike@email.com");
		Person shaun = new Person("Shaun", "shaun@email.com");
		Person sally = new Person("Sally", "sally@email.com");
		Person cesar = new Person("Cesar", "cesar@email.com");

		ArrayList<Person> people = new ArrayList<Person>();
		people.add(mike);
		people.add(shaun);
		people.add(sally);
		people.add(cesar);

上記ペアについて、最初に作ったmapOfPeopleに格納している。正しく格納できているか確認するため、emailとpersonを出力している。

		for (Person person : people) {
			MapExcercise.addToMap(mapOfPeople, person);
		}
		for (String email : mapOfPeople.keySet()) {
			System.out.println(email);
		}

		for (Person person : mapOfPeople.values()) {
			System.out.println(person);
		}

実際に、格納したデータの取得ができるか確認している。containkeyメソッドは、マップに特定のキーがあるかをチェックして、true / falseで値を返すgetメソッドは、指定されたキーに関連づけられた値をマップから取得して返す。存在しない場合は、nullで返す。この場合、Jeffはデータ格納されていないので、nullとfalseで返る。

		System.out.println("Get Mike: " + mapOfPeople.get("mike@email.com"));
		System.out.println("Get Jeff: " + mapOfPeople.get("jeff@email.com"));
		System.out.println("Contains Mike: " + mapOfPeople.containsKey("mike@email.com"));
		System.out.println("Contains Jeff: " + mapOfPeople.containsKey("jeff@email.com"));

	}

こちらは上記コードでも使った、addToMapである。person.getEmail()で、emailをキーとしている。そうした理由は、emailが一意の情報であるため、キーとして機能するからである。一方で名前は一意ではないので、キーとして機能しない。

また、map.put(person.getEmail(), person.getName());としない理由は、Personオブジェクト全体にアクセスできないからである。もしemailと名前を検索したいという特定のニーズであれば、こちらのコードでもいい。ただ、Personオブジェクト全体へのアクセスが必要な場合や、将来的に他の情報にアクセスする可能性がある場合は、map.put(person.getEmail(), person);とした方が適切である。

	private static void addToMap(Map<String, Person> map, Person person) {
		map.put(person.getEmail(), person);
	}

}

Discussion