HashMap

サンプルプログラム

Collection(コレクション)はArrayListばかりではありません。ここではまず、その中の一つ、HashMap(ハッシュマップ)について説明します。以下のサンプルを入力してみてください。

SampleEx601.java
package exday6;

import java.util.*;

public class SampleEx601 {

	public static void main(String[] args) {
		HashMap<String,Integer> map = new HashMap<String,Integer>();
		String nengo[] = { "明治" , "大正" , "昭和" , "平成" };
		map.put(nengo[0], 1868);
		map.put(nengo[1], 1912);
		map.put(nengo[2], 1926);
		map.put(nengo[3], 1989);
		for(String s: nengo){
			System.out.println(s+"元年は、西暦"+map.get(s)+"年");
		}
	}
}
実行結果
明治元年は、西暦1868年
大正元年は、西暦1912年
昭和元年は、西暦1926年
平成元年は、西暦1989年

HashMapは、キーと値を1セットとした要素の集まりを管理するクラスです。書式は以下の通りになります。

HashMapの書式
HashMap<(キーのクラス),(値のクラス)>

通常の配列変数では、キーとして必ず数値をとりますが、HashMapは、キーと値の組み合わせを自由に設定することが可能です。

8行目を見るとわかるとおり、このケースでは、キーとして文字列を、値としてIntegerをとっているので、整数の値をとることが分かります。ここに、値を入れるときは、putメソッドを用います。

HashMapにデータを格納
(HashMapのインスタンス).put(キー,値);

10行目から13行目で、「明治」「大正」などといった年号と、西暦での年を対応させて、格納させています。(図6-1.)さらに、これを取得するのが、getメソッドです。

HashMapからデータの取り出し
(HashMapのインスタンス).get(キー);

図6-1.HashMapの構造

HashMapの構造

このとき、戻り値が、格納されている値になります。なお、HashMapクラスの、主なメソッドは、以下のようになっています。(表6-1.)

表6-1.HashMapクラスの主要メソッド
メソッド 働き
get() 指定したキーの要素を返す。
put() キーと要素を対応させます。
remove() 指定したキーの要素を削除します。
clear() すべてのキーと要素を消去します。
containsKey() 指定したキーの値が存在すれば、true、なければfalseを返します。
isEmpty() 要素がなければ、trueを返します。
size() 要素数を返します。

HashSetクラス

サンプルプログラム

次に、HashMapと並んでよく使用される、HashSet(ハッシュセット)クラスについて説明します。HashSetは、重複なくデータを格納できるコレクションです。追加される要素の中に、同じものが複数含まれていても、一つとみなします。では実際に、サンプルを見てみましょう。

SampleEx602.java
package exday6;

import java.util.*;

public class SampleEx602 {

	public static void main(String[] args) {
		HashSet<String> hs = new HashSet<String>();
		//	ハッシュセットにデータを追加
		hs.add("山田太郎");
		hs.add("山田太郎");
		hs.add("太田美代子");
		hs.add("斉藤五郎");
		hs.add("斉藤五郎");
		//	追加した成分をすべて表示
        for(String s:hs){
        	System.out.println(s);
        }
	}

}
実行結果
太田美代子
斉藤五郎
山田太郎

HashSetには、addメソッドを用いて、データを格納することができます。このプログラムでは、10行目から14行目でその処理を行っています。その結果を表示しているのが、16行目から19行目です。重複して登録されている名前も、一回しか出力されていません。(図6-2.)

図6-2.HashSetの構造

HashMapの構造

HashSetの書式

HashSetクラスの使い方は、以下の通りです。まず、addメソッドで、データを追加することができます。

HashSetクラスでのデータの追加
(HashMapクラスのインスタンス).add(データ);

なお、HashSetクラスの主要なメソッドは、以下のようになります。(表6-2.)

表6-2.HashSetクラスの主要メソッド
メソッド 働き
add() 要素を追加します。
remove() 指定した要素を削除します。
clear() すべて要素を消去します。
contains 指定した要素が存在すれば、true、なければfalseを返します。
isEmpty() 要素がなければ、trueを返します。
size() 要素数を返します。

その他のコレクション

Javaには、このほかにも、たくさんのコレクションクラスが存在します。ここではすべてを紹介しきれませんが、ここまで紹介した、ArrayListHashMapおよびHashSetは、中でも比較的使用頻度が高く、使い勝手の良いものです。なので、まずはこの3つをしっかりと使いこなせるようにしておきましょう。

オブジェクトの比較

サンプルプログラム

ここで、Collectionとは直接関係ないものの、密接な関係を持つオブジェクトの比較について説明していくことにします。コレクションクラスに格納したデータを比較するということは、Java言語に限らず、プログラミングではよく行います。

Javaで、オブジェクトの比較を行う方法には、==演算子を用いる方法と、クラスの、equals()メソッドを使う方法があります。この二つは、よく似ていますが、実は意味が全く違います。実際に、サンプルを通してその違いを見てみましょう。

SampleEx603.java
package exday6;

public class SampleEx603 {

	public static void main(String[] args) {
		String s1 = "ABCDEF";
		String s2 = "ABCDEF";
		String s3 = new String("ABCDEF");
		if(s1.equals(s2)){
			System.out.println("s1とs2の文字列は等しい");
		}else{
			System.out.println("s1とs2の文字列は等しくない");
		}
		if(s1.equals(s3)){
			System.out.println("s1とs3の文字列は等しい");
		}else{
			System.out.println("s1とs3の文字列は等しくない");
		}
		if(s1 == s2){
			System.out.println("s1とs2のオブジェクトは等しい");
		}else{
			System.out.println("s1とs2のオブジェクトは等しくない");
		}
		if(s1 == s3){
			System.out.println("s1とs3のオブジェクトは等しい");
		}else{
			System.out.println("s1とs3のオブジェクトは等しくない");
		}
	}

}
実行結果
s1とs2の文字列は等しい
s1とs3の文字列は等しい
s1とs2のオブジェクトは等しい
s1とs3のオブジェクトは等しくない

このプログラムで、String型の変数s1,s2,s3に、それぞれ、Stringの"ABCDEF"という文字列を代入しています。ただ、s1とs2は、=演算子でも文字列を代入しているのに対し、s3は、Stringクラスをnewすることによってその値を入れています。いったい、何が違うのでしょうか?

比較方法の違い

このサンプルとして取り上げているのは、Stringクラスです。Stringクラスで、文字列が等しいかどうかの比較を行うのは、equalsメソッドです。このメソッドを用いれば、s1,s2,s3ともに、内部の文字列はみな等しく"ABCDEF"であることがわことがわかります。

ところが、==演算子を用いてデータを比較すると、s1とs2は同じものだということがわかりますが(図6-3.②)、s1とs3は違うものだと判断されます。(図6-3.③)この違いは、いったいなぜ発生するのでしょうか?

実は、==演算子は、オブジェクトが等しいかどうかの比較なのです。s1、s2のように、=で代入すると、複数同じ文字列が代入された場合、それらは、同じオブジェクトを指すようになります。しかし、s3のように、newでStringクラスを生成し、文字列を設定した場合、中のオブジェクトは同じでも、オブジェクトとしては違うものを指すのです。

そのため、s1、s2は同一オブジェクトであり、s1とs3は異なるオブジェクトということになるのです。このように、==と、equalsは、意味が異なるので、気をつけましょう。

図6-3.Stringの==とequalsの違い

Stringの==とequalsの違い

練習問題 : 問題6.