Java コレクション関連
[履歴] [最終更新] (2016/06/24 02:33:17)

概要

Java のコレクションは以下の何れかのインターフェースを実装しています。

  • java.util.List
  • java.util.Set
  • java.util.Map

それらとは別の概念として、リストに似たデータ構造の「配列」があります。

  • List と異なり、サイズを変更できません。
  • List と異なり、基本型の配列を宣言できます。

また、Java 8 からは Scala コレクションのようなストリームが利用できます。

配列

import java.util.Arrays;
import java.util.Comparator;

class Main {
    public static void main(String args[]) {

        // 初期化方法
        int[] arr = new int[2];
        int[] arr2 = {2, 1};
        int[][] arr3 = new int[2][2];
        int[][] arr4 = {{1, 2}, {1, 2}};

        // ループ
        for(int i = 0; i < arr.length; ++i) {
        }
        for(int i : arr) {
        }
        for(int[] a : arr3) {
            for(int i : a) {
            }
        }

        // ソート
        Integer[] arr5 = {2, 3, 1};

        Arrays.sort(arr5);
        System.out.println(Arrays.toString(arr5)); //=> [1, 2, 3]

        Arrays.sort(arr2);
        System.out.println(Arrays.toString(arr2)); //=>  [1, 2]

        Arrays.sort(arr5, new Comparator<Integer>(){ // 基本型のソートはできません。ラッパークラスで使用します。
            public int compare(Integer i1, Integer i2) {
                return i2 - i1;
            }
        });
        System.out.println(Arrays.toString(arr5)); //=> [3, 2, 1]

        // 二分探索
        Arrays.sort(arr5); // ニブタンのためにはソートされた配列が必要ですね。
        System.out.println(Arrays.binarySearch(arr5, 2)); //=>  1 (index of '2')

        // コピー
        int[] copied = Arrays.copyOf(arr2, arr2.length);

        // 要素の比較 (基本型は使用できません。ラッパークラスで使用します)
        System.out.println(Arrays.deepEquals(arr5, arr5)); //=> true
    }
}

リスト

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

class Main {
    public static void main(String args[]) {

        // List には ArrayList と LinkedList があります。
        // 
        // ArrayList
        // 内部的に配列を利用しているため、サイズ拡張は低速。主な用途はこちらで。
        // 
        // LinkedList
        // いわゆる連結リスト。先頭と終端への要素の追加は高速。

        // 初期化方法
        List<Integer> list = new ArrayList<Integer>();
        // List<Integer> list = new ArrayList<>(); // 省略形
        // List<Integer> list = new ArrayList<>(2); // 初期メモリを確保する要素数を指定

        // 別の初期化方法
        List<Integer> list2 = Arrays.asList(1, 2, 3);
        List<Integer> list3 = Collections.emptyList(); // 空のリスト

        // 配列との相互変換
        Integer[] arr = list.toArray(new Integer[list.size()]);
        List<Integer> list4 = Arrays.asList(arr);

        // 追加
        list.add(123);

        // 削除
        list.remove(0); // index で指定
        list.remove(new Integer(0)); // 値で指定
        list.clear(); // すべて空にする
        list.removeIf(i -> i > 0); // Java 8 のみ

        // List の連結
        list.addAll(list2);

        // 値の設定
        list.set(0, -123);

        // 値の取得
        System.out.println(list.get(0)); // index で指定

        // サイズ
        System.out.println(list.size());

        // ループ
        for(Integer i : list) {
        }
        list.forEach(i -> System.out.println(i)); // Java 8 のみ

        // ソート
        Collections.sort(list);
        Collections.reverse(list); // reverse sort
        Collections.sort(list, new Comparator<Integer>(){
            public int compare(Integer i1, Integer i2) {
                return i2 - i1;
            }
        });

        // 置換
        list.replaceAll(i -> i * i); // java 8

        // その他
        System.out.println(list.isEmpty());
        System.out.println(list.contains(123));
        System.out.println(list.indexOf(123)); // 最初の index (-1 if not found)
        System.out.println(list.lastIndexOf(123)); // 最後の index (-1 if not found)
    }
}

マップと集合

import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;

class Main {
    public static void main(String args[]) {

        // マップ
        Map<String, Integer> map = new HashMap<>();
        map.put("key", 123);
        map.remove("key");
        map.clear();
        for(String key : map.keySet()) {
            System.out.println(map.get(key));
        }
        for(Integer value : map.values()) {
            System.out.println(value);
        }
        map.forEach((key, value) -> System.out.println(key + ": " + value)); // java 8
        System.out.println(map.get("key"));
        System.out.println(map.getOrDefault("key2", -123)); // java 8
        System.out.println(map.containsKey("key"));
        System.out.println(map.containsValue(123));
        System.out.println(map.size());
        System.out.println(map.isEmpty());

        // 集合
        Set<String> set = new HashSet<>();
        Set<String> set2 = new HashSet<>();
        set2.addAll(set);
        set.add("a");
        set.contains("a");
        set.remove("a");
        set.clear();
        set.size();
        set.isEmpty();
        for(String str : set) {
        }
        set.forEach(s -> System.out.println(s)); // java 8
    }
}

ストリーム (Java 8)

import java.util.List;
import java.util.Arrays;
import java.util.stream.Stream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.DoubleStream;
import java.util.Optional;

class Main {
    public static void main(String args[]) {

        // 新規作成
        Stream<Integer> s1 = Stream.of(1, 2, 3);

        IntStream s2 = IntStream.of(1, 2, 3);
        LongStream s3 = LongStream.of(1, 2, 3);
        DoubleStream s4 = DoubleStream.of(1.0, 2.0, 3.0);

        IntStream s5 = IntStream.range(1, 100); // 1, 2, ..., 99
        Stream<Integer> s6 = Stream.iterate(0, i -> i + 1);

        // 他のコレクションから変換
        List<Integer> list = Arrays.asList(1, 2, 3);
        Stream<Integer> s7 = list.stream();

        // 配列から変換
        Integer[] arr = {1, 2, 3};
        Stream<Integer> s8 = Arrays.stream(arr);
        Stream<Integer> s9 = Stream.of(arr);

        // 一度使用すると使えなくなります (ストリームは自動で閉じます)
        Stream<Integer> stream = Stream.of(1, 2, 3);
        stream.forEach(i -> System.out.println(i));
        //stream.forEach(i -> System.out.println(i)); // IllegalStateException: stream has already been operated upon or closed

        // 基本的な操作
        Stream.of(1, 2, 3).filter(i -> i > 0);
        Stream.of(1, 2, 3).map(i -> i * i);
        Stream.of(1, 2, 3).flatMap(i -> Stream.of(i, i * 10)); // flatten
        Stream.of(1, 2, 3).sorted((i1, i2) -> i1 - i2);
        Stream.of(1, 2, 3).distinct(); // 重複の削除
        Stream.of(1, 2, 3).forEach(i -> System.out.println(i));
        Stream.of(1, 2, 3).count(); // 無限ストリームのとき、無限ループになります。
        Stream.of(1, 2, 3).limit(2).count();
        IntStream.of(1, 2, 3).sum();
        Stream.of("a", "b").mapToInt(s -> s.length()); // IntStream 化

        // 結合
        Stream.concat(Stream.of(1, 2, 3), Stream.of(1, 2, 3)).count();

        // 条件判定
        Stream.of(1, 2, 3).allMatch(i -> i > 0); // true if all true
        Stream.of(1, 2, 3).anyMatch(i -> i > 0); // true if any true
        Stream.of(1, 2, 3).noneMatch(i -> i > 0); // true if all false

        // MapReduce の Reduce
        Optional<Integer> iOpt = Stream.of(1, 2, 3).reduce((i1, i2) -> i1 + i2);
        Integer i = Stream.of(1, 2, 3).reduce(0, (i1, i2) -> i1 + i2); // 初期値あり (必ず結果が存在するため Optional ではなくなります)
    }
}

他のコレクションへの変換

import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.util.Map;
import java.util.List;
import java.util.Set;

class Main {
    public static void main(String args[]) {

        // Map に変換 (複数の List でグルーピング)
        Map<Boolean, List<Integer>> map = Stream.of(-1, -2, -3, 1, 2, 3).collect(Collectors.groupingBy(i -> i > 0)); // 正負でグルーピング
        System.out.println(map.get(true)); //=> [1, 2, 3]
        System.out.println(map.get(false)); //=> [-1, -2, -3]

        Map<Character, List<String>> map2 = Stream.of("Java", "JavaScript", "C++").collect(Collectors.groupingBy(s -> s.charAt(0)));
        System.out.println(map2.get('A')); //=> null
        System.out.println(map2.get('C')); //=> [C++]
        System.out.println(map2.get('J')); //=> [Java, JavaScript]

        // Map に変換
        Map<String, Integer> map3 = Stream.of(1, 2, 3)
            .collect(Collectors.toMap(i -> "key" + i, // key
                                      i -> i * i)); // value
        System.out.println(map3); //=> {key1=1, key2=4, key3=9}

        // List に変換
        List<Integer> list = Stream.of(1, 2, 3).collect(Collectors.toList());

        // Set に変換
        Set<Integer> set = Stream.of(1, 2, 3).collect(Collectors.toSet());

        // 配列に変換
        Object[] arr = Stream.of(1, 2, 3).toArray();
        Integer[] intArr = Stream.of(1, 2, 3).toArray(Integer[]::new);
    }
}
関連ページ
    ラムダ式 (Java 8) import java.util.Arrays; import java.util.List; import java.util.function.Function; class Main { public static String myFunc(Function<String, String> callback) { return cal
    概要 Rails における ERB と同様に、Spring Boot でもテンプレートエンジンを利用できます。今回は特に Thymeleaf (タイムリーフ) のサンプルコードを、こちらのページで構築した環境をもとにまとめます。 公式ドキュメント Serving Web Content with Spring MVC