HashSetによるSetの利用
「Set」は、ユニークな値を保持するためのものでした。これを実装したものとしては「HashSet」というクラスが一般的に用いられます。これは、ArrayListなどと同じように、値をaddやremoveで出し入れするだけのシンプルなクラスです。
[HashSet].add( オブジェクト );
[HashSet].remove( オブジェクト );
int 変数 = [HashSet].size();
HashSetは、常に「すべての値が異なる」状態となります。しかし、現実問題として、「既にある値をまたaddしてしまった」なんてこともあるはずです。そうしたときはどうなるのでしょうか。実際に試してみましょう。
package codezine.java; import java.util.*; public class Sample { public static void main(String[] args) { HashSet set = new HashSet(); set.add("eins"); set.add("zwei"); set.add("drei"); set.add("zwei"); set.add("drei"); set.add("eins"); Object[] arr = set.toArray(); for(Object obj:arr){ System.out.println(obj); } } }
ここでは、「eins」「zwei」「drei」という値を2回ずつaddしてみました。そして、保管されているすべての値を出力してみると、「eins」「zwei」「drei」がそれぞれ1つずつしか保管されていないことが分かります。何度addしても、同じ値は常に1つしか保管されないのです。
また、ここではHashSetに保管されている値をすべて取り出すのに「toArray」というメソッドを利用しています。これは、保管しているオブジェクトをObject配列としてまとめたものを返すものです。こうして配列として値を取り出せば、後は自由に中身を扱えるようになります。
イテレータの考え方
3種類のコレクションをそれぞれ見てみると、List以外は「全要素を処理する」というのが意外に面倒であることが分かります。HashSetではObject配列として取り出して処理しないといけませんでしたし、HashMapにいたってはそれすら用意されていない状態です。
コレクション関係では、要素を順に取り出して処理していくということがよくあります。こうした場合に、覚えておきたいのが「イテレータ」というものです。これは、コレクションから値を順に取り出していくためのもので、日本語では「反復子」と呼ばれたりします。
これは、「Iterator」というインターフェースとして用意されています。HashSetなどいくつかのクラスでは、Iteratorを使って値を順に取り出していくことができるようになっています。実際に簡単な例を挙げておきましょう。
package codezine.java; import java.util.*; public class Sample { public static void main(String[] args) { HashSet set = new HashSet(); set.add("eins"); set.add("zwei"); set.add("drei"); Iterator iterator = set.iterator(); while(iterator.hasNext()){ String val = (String)iterator.next(); System.out.println(val); } } }
先ほどのHashSetに値を保管し、順に取り出して表示するサンプルを、Iterator利用の形に書き換えてみました。HashSetの「iterator」メソッドを使ってiteratorを取得しています。Iteratorには、順に値を取り出していくために以下のようなメソッドが用意されています。
Object 変数 = [Iterator].next();
boolean 変数 = [Iterator].hasNext();
[Iterator].remove();
ここでは、while(iterator.hasNext())として値が残っている間、繰り返しを行っています。そしてiterator.next()で順に値を取り出し、それを表示しています。Iteratorも値はObjectとして取り出されるので、必要に応じて元のクラスにキャストします。
HashMapでのIterator利用
iteratorメソッドがないHashMapなどでIteratorを利用したい場合は、どうすればいいのでしょうか。直接iteratorを取り出すことはできませんが、実はHashMapは、保管されているすべてのキーをSetとして取り出すことが可能です。そこで「HashMap→Set→Iterator」という形で取り出します。
package codezine.java; import java.util.*; public class Sample { public static void main(String[] args) { HashMap map = new HashMap(); map.put("yamada","taro@mail.co.jp"); map.put("hanako", "hanako@yamada.com"); map.put("tuyano", "tuyano@mac.com"); Set keys = map.keySet(); Iterator iterator = keys.iterator(); while(iterator.hasNext()){ String key = (String)iterator.next(); String value = (String)map.get(key); System.out.println("KEY: " + key + ", VALUE: " + value); } } }
ここでは、HashMapの「keySet」というメソッドを使って、保管されているキーだけをSetにまとめて取り出しています。Mapはキーを使って値を管理しますから、キーは重複する値は存在しない、すなわちSetな値が取り出せます。
こうしてSetとしてキーを取得したら、そこからIteratorを取り出し、繰り返しで値を順に処理していきます。コレクション関係のクラスは、このようにあるクラスから別のクラスのインスタンスを取り出して処理する、という使い方をすることがあります。


