Java の HashSet と TreeSet
Java の Set インターフェイス
コレクション の概要説明では、Set は 「順番は問わないが各要素へアクセス可能としたいとき」に使うということを説明しました。
これは確かにその通りで、これは出現したか?出現していない?とか、そういう判断を行なうのは Set コレクションを使うと便利です。
Set というのは「集合」という意味で、要はひとつの集合を作り、その中に特定の要素があるかどうか?という診断に使うと便利です。
代表的な Set の実装として、ここでは HashSet と TreeSet を取り上げます。
Java の HashSet
まずは、HashSet というのはハッシュを使って、要素の保存場所を決定します。
このため、要素の追加削除変更という操作が、要素の数に関わらず一定の時間で実行可能です。
その代わり、保存順番が全く保障されません。
実行例を見てください。
package settest1;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetTest1 {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("Texas");
set.add("Washington");
set.add("California");
set.add("Hawaii");
if(set.contains("California")){
System.out.println("True");
}
else{
System.out.println("False");
}
for(String s : set){
System.out.println(s);
}
}
}
ここで String を要素に持つ HashSet を作り、そこに Texas, Washington, California, Hawaii という単語を add メソッドで追加します。
次に contains メソッドで "California" がセットに含まれるかどうかチェック。(これは True を返すはずですね) そして、最後に要素を出力しています。
True California Washington Hawaii Texas
確かに True が返っています。
要素が出現する順番は、要素を追加した順番でもアルファベット順でもありません。
さて、次に TreeSet で同様のことを実施してみましょう。
Java の TreeSet
TreeSet はソートされたセット (sorted set) です。即ち、要素がソートされて格納されます。
package settest1;
import java.util.Set;
import java.util.TreeSet;
public class SetTest1 {
public static void main(String[] args) {
Set<String> set = new TreeSet<>();
set.add("Texas");
set.add("Washington");
set.add("California");
set.add("Hawaii");
if(set.contains("California")){
System.out.println("True");
}
else{
System.out.println("False");
}
for(String s : set){
System.out.println(s);
}
}
}
コードの変更は単に TreeSet を new しているところだけです。
実行結果は次の通りになります。
True California Hawaii Texas Washington
California, Hawaii, Texas, Washington というアルファベット順にソートされていますね。
HashSet と TreeHash のポイントのまとめ
ポイントをまとめると、HashSet と TreeHash のMap クラスの使い分けは次のようにいえます。
- 通常は高速な HashSet を使う
- ただし HashSet 要素の順番は保障されない
- ソートが必要なときだけ TreeHash を検討する
- いずれも要素は重複しない
Map の Iterator の使い方
最後に、一応 Iterator の使い方をみておきましょう。
package settest1;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class SetTest1 {
public static void main(String[] args) {
...
Iterator<String> itr = set.iterator();
while(itr.hasNext()){
System.out.println(itr.next());
}
...
はじめの例では for で set から直接値を引き出していましたが、このように Iterator を明示的に使い hasNext, next で要素をたどることも可能です。