【Java】Mapについて
概要
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