LoginSignup
10
13

More than 5 years have passed since last update.

[Java] StreamのCollectorsのメモ

Last updated at Posted at 2017-11-19

個人的なメモ

  • 忘れてしまうので、よく使いそうなパターンを記載
  • 本当によく使うパターンは、自家版 Collectorsクラス/メソッドを作ってもいいのかも

Collectors#toMap()

LinkedHashMapを使いたい

明示的に LikedHashMap を使いたい。
ついでに、キー重複を許したい。

    public static <T, K, V> Collector<T, ?, Map<K, V>> toMap(
            Function<? super T, ? extends K> keyMapper,
            Function<? super T, ? extends V> valueMapper) {

        return Collectors.toMap(
                keyMapper,
                valueMapper,
                (a, b) -> b,
                LinkedHashMap::new);
    }

キー重複を許したくない場合には、例外を投げる。

(a, b) -> { throw new IllegalStateException(~); }

詳細は、標準の2引数 Collectors#toMap() を参照。

TreeMap を使いたい

キーで自然にソートしたい。
ほぼ同じ。

    public static <T, K, V> Collector<T, ?, Map<K, V>> toTreeMap(
            Function<? super T, ? extends K> keyMapper,
            Function<? super T, ? extends V> valueMapper) {

        return Collectors.toMap(
                keyMapper,
                valueMapper,
                (a, b) -> b,
                TreeMap::new); // ★ここ
    }

TreeMapにComparator を指定したいときは、コンストラクタ参照ではなくラムダ式で指定。

Collectors#toSet()

LinkedHashSetを使いたい

ここは toSet() ではなく、toCollection() を使うのがポイント。

    public static <T> Collector<T, ?, Set<T>> toSet() {
        return Collectors.toCollection(LinkedHashSet::new);
    }

TreeSetを使いたい

基本同じ。

    public static <T> Collector<T, ?, Set<T>> toTreeSet() {
        return Collectors.toCollection(TreeSet::new);
    }

Collectors#groupingBy

LinkedHashMapを使いたい

    public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(
            Function<? super T, ? extends K> classifier) {

        return Collectors.groupingBy(classifier,
                LinkedHashMap::new, // ★ここ
                Collectors.toList());
    }

TreeMapを使いたい

同じ。

    public static <T, K> Collector<T, ?, Map<K, List<T>>> orderedGroupBy(
            Function<? super T, ? extends K> classifier) {

        return Collectors.groupingBy(classifier,
                TreeMap::new, // ★ここ
                Collectors.toList());
    }

要素をListじゃなくSetにしたい

…良いメソッド名が思いつかない。

    public static <T, K> Collector<T, ?, Map<K, Set<T>>> groupingBySet(
            Function<? super T, ? extends K> classifier) {

        return Collectors.groupingBy(classifier,
                TreeMap::new,
                Collectors.toCollection(LinkedHashSet::new)); // ★ここ
    }

もちろん目的に応じて、TreeSetや、普通の Collectors.toSet() でもOK。

グルーピング時にListに詰める要素も変換したい

    public static <T, K, D> Collector<T, ?, Map<K, List<D>>> groupingBy(
            Function<? super T, ? extends K> classifier,
            Function<? super T, ? extends D> mapper) {

        return Collectors.groupingBy(classifier,
                LinkedHashMap::new,
                Collectors.mapping(mapper, // ★ここ
                        Collectors.toList()));
    }

もちろん、List じゃなくて Set でもOK。

Collectors#collectingAndThen

変更不可な Map や List を生成したい場合。

    public static <T, K, V> Collector<T, ?, Map<K, V>> toConstMap(
            Function<? super T, ? extends K> keyMapper,
            Function<? super T, ? extends V> valueMapper) {

        return Collectors.collectingAndThen(
                Collectors.toMap(
                    keyMapper,
                    valueMapper),
                Collections::unmodifiableMap);
    }
10
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
13