java-beginner.com ブログ

プログラミングを学習するブログ(Javaをメインに)

SetのtoArrayメソッド

投稿日:

最終更新日:2016年08月09日

アイキャッチ

こんにちは。「Javaを復習する初心者」です。

今回はSetインターフェースのtoArrayメソッドを使って、3つのクラスHashSet、LinkedHashSet、TreeSetの出力を確認しました。

出力の順番

結論からまとめてしまうと、出力の順は以下になります。

クラス 順序
HashSet 決まっていない
LinkedHashSet 追加順
TreeSet ソート順

TreeSetのインスタンスをTreeSet()で生成した場合、格納する要素のクラスはComparable<T>インターフェースを実装している必要があります。オーバーライドされたcompareToメソッドが定める順序に従ってソートされるということです。コンストラクタTreeSet(Comparator<? super E> comparator)を使う方法もあります。

今回はIntegerクラスとStringクラスそれぞれを使用して、出力を確認してました。それぞれ、Comparableインターフェースを実装しています。

Integerの場合

Integerの場合は次のように作りました。

  1. List<Integer>型変数を1つ用意し、ArrayListのインスタンスを格納する。
  2. Set<Integer>型変数3つ用意し、以下のクラスのインスタンスを格納する。
    1. HashSet
    2. LinkedHashSet
    3. TreeSet
  3. 0から999の範囲の乱数を10個、上記のListと3つのSetに格納する。
  4. 上記3つのSetを配列に変換し、それぞれ配列変数a, b, cに格納する。
  5. 以下の形式で出力する。ただし、3行目以降は繰り返しカウンタiが0から配列aの長さ未満まで繰り返し出力する。
    行数 形式
    1行目
    書式 “%-13s|%-13s|%-13s|%-13s”
    埋め字 “ArrayList”, “HashSet”, “LinkedHashSet”, “TreeSet”
    2行目 “——————————————————-“
    3行目以降
    書式 “%13d|%13d|%13d|%13d”
    埋め字 list.get(i), a[i], b[i], c[i]

以下はソースと実行結果です。

ソース

package practice.test20160809;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;

public class SetInteger {

    public static void main(String[] args) {

        List<Integer> list = new ArrayList<>();
        Set<Integer> hashSet = new HashSet<>();
        Set<Integer> linkedHashSet = new LinkedHashSet<>();
        Set<Integer> treeSet = new TreeSet<>();

        // 乱数格納
        Random random = new Random();
        int randomNum = 0;
        for (int i = 0; i < 10; i++) {
            randomNum = random.nextInt(1000);
            list.add(randomNum);
            hashSet.add(randomNum);
            linkedHashSet.add(randomNum);
            treeSet.add(randomNum);
        }

        // 配列に変換
        Integer[] a = hashSet.toArray(new Integer[0]);
        Integer[] b = linkedHashSet.toArray(new Integer[0]);
        Integer[] c = treeSet.toArray(new Integer[0]);

        // 出力
        System.out.printf("%-13s|%-13s|%-13s|%-13s", "ArrayList", "HashSet", "LinkedHashSet", "TreeSet");
        System.out.println();
        System.out.println("-------------------------------------------------------");
        for (int i = 0; i < a.length; i++) {
            System.out.printf("%13d|%13d|%13d|%13d", list.get(i), a[i], b[i], c[i]);
            System.out.println();
        }

    }

}

結果

ArrayList    |HashSet      |LinkedHashSet|TreeSet      
-------------------------------------------------------
          731|          994|          731|          109
          739|          739|          739|          218
          994|          531|          994|          333
          613|          613|          613|          531
          333|          218|          333|          613
          531|          731|          531|          731
          939|          939|          939|          739
          218|          333|          218|          766
          766|          109|          766|          939
          109|          766|          109|          994

TreeSetは数値の昇順になってます。これはIntegerクラスがComparable<Integer>を実装して、このように並ぶようにしているからです。ArrayListの要素i番目が格納順です。なので、LinkedHashSetの出力と同じ順序です。

Stringの場合

Stringの場合は、Integerのときと大体同じ作りですが、ArrayListは使ってません。文字列なので格納する内容は英語小文字のランダムな並びを作ることにしました。その部分は次のようなフローです。

  1. 単語の長さrandomLengthを1から10の範囲の乱数で決定する。
  2. それぞれの文字を’a’ + [0から25までの乱数]で決定する。

以下はソースと実行結果です。

ソース

package practice.test20160809;

import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;

public class SetString {

    public static void main(String[] args) {

        Set<String> hashSet = new HashSet<>();
        Set<String> linkedHashSet = new LinkedHashSet<>();
        Set<String> treeSet = new TreeSet<>();

        // ランダム文字列格納
        Random random = new Random();
        for (int i = 0; i < 10; i++) {

            // 単語生成
            int randomLength = random.nextInt(10) + 1;
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < randomLength; j ++) {
                char c = (char)('a' + random.nextInt(26));
                sb.append(c);
            }
            String s = sb.toString();
            hashSet.add(s);
            linkedHashSet.add(s);
            treeSet.add(s);
        }

        // 配列に変換
        String[] a = hashSet.toArray(new String[0]);
        String[] b = linkedHashSet.toArray(new String[0]);
        String[] c = treeSet.toArray(new String[0]);

        // 出力
        System.out.printf("%-13s|%-13s|%-13s", "HashSet", "LinkedHashSet", "TreeSet");
        System.out.println();
        System.out.println("-----------------------------------------");
        for (int i = 0; i < a.length; i++) {
            System.out.printf("%-13s|%-13s|%-13s", a[i], b[i], c[i]);
            System.out.println();
        }

    }

}

結果

HashSet      |LinkedHashSet|TreeSet      
-----------------------------------------
ediznizl     |n            |cg           
wxdnr        |cg           |ediznizl     
cg           |wxdnr        |mnmuxikhm    
unip         |ediznizl     |n            
v            |mnmuxikhm    |nmjs         
mnmuxikhm    |unip         |skg          
nmjs         |v            |unip         
n            |skg          |v            
skg          |zkp          |wxdnr        
zkp          |nmjs         |zkp          

上記のようにTreeSetは辞書式順序になってます。これもIntegerクラスと同じようにStringクラスがそのように実装しているからです。