Yomiage
メニュー

Java実践講座 07:コレクション・ジェネリクス・計算量

更新 2026/9/27 6:22:11 公開

投稿者: しゅりりん

到達点は、List、Set、Mapを目的に合わせて選ぶことです。前提は第06回です。

保存したい関係から選ぶ

Listは順序と重複を持つ列、Setは重複しない集合、Mapはキーから値への対応です。記事を表示順に持つならList、既読IDを管理するならSet、IDから記事を探すならMapが候補です。

import java.util.*;

public class Main {
    static int sum(List<? extends Number> values) {
        int total = 0;
        for (Number value : values) total += value.intValue();
        return total;
    }

    public static void main(String[] args) {
        List<String> words = List.of("java", "rust", "java");
        Set<String> unique = new HashSet<>(words);
        Map<String, Integer> counts = new TreeMap<>();
        for (String word : words) counts.merge(word, 1, Integer::sum);
        System.out.println(unique.size());
        System.out.println(counts);
        System.out.println(sum(List.of(10, 20, 30)));
    }
}

Main.javaの出力は2、キー順でjavaが2とrustが1の対応、60です。HashSetの反復順は保証に頼らず、表示順を決めたい場合は並べ替えます。ここではMapにTreeMapを使い、順序を明確にしました。

ジェネリクスの List<String> は文字列のリストという型の約束です。List<Integer> はそのまま List<Number> の代わりには渡せません。もし渡せたら、受け手がDoubleを追加できてしまうためです。読み取り中心の引数なら ? extends Number、特定の型の値を渡し込む用途なら ? super Integer が候補になります。

件数が増えたときに考える

ArrayListの添字アクセスは定数時間ですが、途中への挿入は後続要素を移動させます。HashMapの検索は平均的には定数時間が期待でき、TreeMapは対数時間です。二重ループで全組合せを比べる処理は、件数が10倍になると比較回数が約100倍になることがあります。

Mapのキーに可変オブジェクトを使い、登録後にequalsやhashCodeに関係する値を変えると検索を壊す恐れがあります。キーには安定したIDや不変の値を使います。List.ofが返すリストは変更できません。変更するならArrayListにコピーします。

練習と解答

練習:二つの名簿に共通する名前を、重複なしで取得してください。

解答例:一方をHashSetにし、もう一方の名前が含まれるかを調べ、結果もSetへ入れます。全組合せを比較するより、平均的に合計件数に比例する処理にできます。大文字・小文字を区別するかも仕様として決めましょう。

公式資料

コレクションとジェネリクスが参照先です。


Java全20回の目次 | 前の回 | 次の回

このブラウザでは Web Speech API が利用できません。

1 / 18 · 停止中