Java : Collectors - API使用例

Collectors (Java SE 18 & JDK 18) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。


概要

要素をコレクションに蓄積したり、さまざまな条件に従って要素を要約するなど、有用な各種リダクション操作を実装したCollector実装。

クラス構成

Collectors クラスは、さまざまな処理をする Collector インタフェースを作成します。
Collectorインタフェースは、ストリームの終端操作である Stream.collect のパラメータに指定します。

ストリームを Map に変換する例です。

record Item(String name, int value) {
}

final var stream = Stream.of(
        new Item("aaa", 10),
        new Item("bbb", 20),
        new Item("ccc", 30)
);

final var ret = stream.collect(
        Collectors.toUnmodifiableMap(
                Item::name, Item::value));

System.out.println(ret); // {aaa=10, ccc=30, bbb=20}

他にも、文字列として連結することもできます。

final var stream = Stream.of("aaa", "bbb", "ccc");

final var ret = stream.collect(Collectors.joining("-"));
System.out.println(ret); // aaa-bbb-ccc

関連記事:ストリームの基本 (Stream)


メソッド

static <T> Collector<T,?,Double> averagingDouble (ToDoubleFunction<? super T> mapper)

入力要素にdouble値関数を適用した結果の算術平均を生成するCollectorを返します。

final var stream = Stream.of(1.0, 2.0, 3.0, 4.0);

final var ret = stream.collect(Collectors.averagingDouble(value -> value));
System.out.println(ret); // 2.5

static <T> Collector<T,?,Double> averagingInt (ToIntFunction<? super T> mapper)

入力要素にint値関数を適用した結果の算術平均を生成するCollectorを返します。

final var stream = Stream.of(1, 2, 3, 4);

final var ret = stream.collect(Collectors.averagingInt(value -> value));
System.out.println(ret); // 2.5

static <T> Collector<T,?,Double> averagingLong (ToLongFunction<? super T> mapper)

入力要素にlong値関数を適用した結果の算術平均を生成するCollectorを返します。

final var stream = Stream.of(10000000000L, 20000000000L, 30000000000L, 40000000000L);

final var ret = stream.collect(Collectors.averagingLong(value -> value));
System.out.println(ret); // 2.5E10

static <T, A, R, RR> Collector<T,A,RR> collectingAndThen (Collector<T,A,R> downstream, Function<R,RR> finisher)

追加の仕上げ変換が実行されるようにCollectorを適応させます。

関連:toUnmodifiableList()

final var stream = Stream.of("aaa", "bbb", "ccc");

final var ret = stream.collect(Collectors.collectingAndThen(
        Collectors.toList(),
        Collections::unmodifiableList));
System.out.println(ret); // [aaa, bbb, ccc]

ret.add("xxx"); // java.lang.UnsupportedOperationException

static <T> Collector<T,?,Long> counting ()

T型の要素を受け入れて、入力要素の数をカウントする、Collectorを返します。

final var stream = Stream.of("aaa", "bbb", "ccc");

final var ret = stream.collect(Collectors.counting());
System.out.println(ret); // 3

static <T, A, R> Collector<T,?,R> filtering (Predicate<? super T> predicate, Collector<? super T,A,R> downstream)

述語を各入力要素に適用し、述語がtrueを返す場合にのみ累積することによって、Collectorを同じ型の要素Tを受け入れる要素に適合させます。

final var stream = Stream.of(1, 20, 3, 40);

final var ret = stream.collect(Collectors.filtering(
        value -> value >= 10,
        Collectors.toUnmodifiableList()));

System.out.println(ret); // [20, 40]
final var stream = Stream.of(1, 20, 3, 40);

final var ret = stream.collect(
        Collectors.groupingBy(
                (value) -> value % 2 == 0 ? "even" : "odd",
                Collectors.filtering(
                        value -> value >= 10,
                        Collectors.toUnmodifiableList())));

System.out.println(ret); // {even=[20, 40], odd=[]}

static <T, U, A, R> Collector<T,?,R> flatMapping (Function<? super T,? extends Stream<? extends U>> mapper, Collector<? super U,A,R> downstream)

蓄積前に各入力要素にフラット・マッピング関数を適用することにより、型Uの要素を受け入れるCollectorを型Tの受け入れ要素に受け入れます。

record Team(String name, List<String> members) {
}

final var stream = Stream.of(
        new Team("aaa", List.of("a-1", "a-2")),
        new Team("bbb", List.of("b-1", "b-2", "b-3"))
);

final var ret = stream.collect(
        Collectors.flatMapping(
                team -> team.members().stream(),
                Collectors.toUnmodifiableList()));

System.out.println(ret); // [a-1, a-2, b-1, b-2, b-3]
record Team(String name, List<String> members) {
}

final var stream = Stream.of(
        new Team("aaa", List.of("a-1", "a-2")),
        new Team("aaa", List.of("a-3", "a-4")),
        new Team("bbb", List.of("b-1", "b-2", "b-3"))
);

final var ret = stream.collect(
        Collectors.groupingBy(
                Team::name,
                Collectors.flatMapping(
                        team -> team.members().stream(),
                        Collectors.toUnmodifiableList())));

System.out.println(ret); // {aaa=[a-1, a-2, a-3, a-4], bbb=[b-1, b-2, b-3]}

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

分類関数に従って要素をグループ化し、結果をMapに格納して返す、T型の入力要素に対する「グループ化」操作を実装したCollectorを返します。

final var stream = Stream.of(1, 2, 3, 4, 5);

// 偶数・奇数でグルーピングします。
final var ret = stream.collect(
        Collectors.groupingBy((value) -> value % 2 == 0 ? "even" : "odd"));

System.out.println(ret); // {even=[2, 4], odd=[1, 3, 5]}

static <T, K, D, A, M extends Map<K, D>> Collector<T,?,M> groupingBy (Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream)

分類関数に従って要素をグループ化した後、指定された下流Collectorを使って特定のキーに関連付けられた値のリダクション操作を実行する、T型の入力要素に対するカスケード「グループ化」操作を実装したCollectorを返します。

record Book(String category, String title, int price) {
}

final var stream = Stream.of(
        new Book("Travel", "aaa", 10),
        new Book("History", "bbb", 20),
        new Book("Cooking", "ccc", 50),
        new Book("Cooking", "ddd", 40),
        new Book("History", "eee", 30),
        new Book("History", "fff", 60)
);

final var ret = stream.collect(Collectors.groupingBy(
        Book::category,
        TreeMap::new,
        Collectors.mapping(
                Book::title,
                Collectors.toUnmodifiableList())));

// {Cooking=[ccc, ddd], History=[bbb, eee, fff], Travel=[aaa]}
System.out.println(ret);

static <T, K, A, D> Collector<T,?,Map<K,D>> groupingBy (Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)

分類関数に従って要素をグループ化した後、指定された下流Collectorを使って特定のキーに関連付けられた値のリダクション操作を実行する、T型の入力要素に対するカスケード「グループ化」操作を実装したCollectorを返します。

record Book(String category, String title, int price) {
}

final var stream = Stream.of(
        new Book("Travel", "aaa", 10),
        new Book("History", "bbb", 20),
        new Book("Cooking", "ccc", 50),
        new Book("Cooking", "ddd", 40),
        new Book("History", "eee", 30),
        new Book("History", "fff", 60)
);

final var ret = stream.collect(Collectors.groupingBy(
        Book::category,
        Collectors.mapping(
                Book::title,
                Collectors.toUnmodifiableList())));

// {Travel=[aaa], Cooking=[ccc, ddd], History=[bbb, eee, fff]}
System.out.println(ret);

static <T, K> Collector<T,?,ConcurrentMap<K,List<T>>> groupingByConcurrent (Function<? super T,? extends K> classifier)

分類関数に従って要素をグループ化する、T型の入力要素に対する「グループ化」操作を実装した並行Collectorを返します。

final var stream = Stream.of(1, 2, 3, 4, 5).parallel();
System.out.println(stream.isParallel()); // true

// 偶数・奇数でグルーピングします。
final var ret = stream.collect(
        Collectors.groupingByConcurrent(
                (value) -> value % 2 == 0 ? "even" : "odd"));

System.out.println(ret); // {even=[4, 2], odd=[3, 5, 1]}

static <T, K, A, D, M extends ConcurrentMap<K, D>> Collector<T,?,M> groupingByConcurrent (Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream)

分類関数に従って要素をグループ化した後、指定された下流Collectorを使って特定のキーに関連付けられた値のリダクション操作を実行する、T型の入力要素に対するカスケード「グループ化」操作を実装した並行Collectorを返します。

record Book(String category, String title, int price) {
}

final var stream = Stream.of(
        new Book("Travel", "aaa", 10),
        new Book("History", "bbb", 20),
        new Book("Cooking", "ccc", 50),
        new Book("Cooking", "ddd", 40),
        new Book("History", "eee", 30),
        new Book("History", "fff", 60)
).parallel();

System.out.println(stream.isParallel()); // true

final var ret = stream.collect(Collectors.groupingByConcurrent(
        Book::category,
        ConcurrentSkipListMap::new,
        Collectors.mapping(
                Book::title,
                Collectors.toUnmodifiableList())));

// {Cooking=[ddd, ccc], History=[fff, eee, bbb], Travel=[aaa]}
System.out.println(ret);

static <T, K, A, D> Collector<T,?,ConcurrentMap<K,D>> groupingByConcurrent (Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)

分類関数に従って要素をグループ化した後、指定された下流Collectorを使って特定のキーに関連付けられた値のリダクション操作を実行する、T型の入力要素に対するカスケード「グループ化」操作を実装した並行Collectorを返します。

record Book(String category, String title, int price) {
}

final var stream = Stream.of(
        new Book("Travel", "aaa", 10),
        new Book("History", "bbb", 20),
        new Book("Cooking", "ccc", 50),
        new Book("Cooking", "ddd", 40),
        new Book("History", "eee", 30),
        new Book("History", "fff", 60)
).parallel();

System.out.println(stream.isParallel()); // true

final var ret = stream.collect(Collectors.groupingByConcurrent(
        Book::category,
        Collectors.mapping(
                Book::title,
                Collectors.toUnmodifiableList())));

// {Travel=[aaa], Cooking=[ddd, ccc], History=[eee, fff, bbb]}
System.out.println(ret);

static Collector<CharSequence,?,String> joining ()

入力要素を検出順に連結して1つのStringにするCollectorを返します。

final var stream = Stream.of("aaa", "XXX", "bbb", "YYY");

final var ret = stream.collect(Collectors.joining());
System.out.println(ret); // aaaXXXbbbYYY

static Collector<CharSequence,?,String> joining (CharSequence delimiter)

入力要素を検出順に指定された区切り文字で区切りながら連結するCollectorを返します。

final var stream = Stream.of("aaa", "XXX", "bbb", "YYY");

final var ret = stream.collect(Collectors.joining("-"));
System.out.println(ret); // aaa-XXX-bbb-YYY

static Collector<CharSequence,?,String> joining (CharSequence delimiter, CharSequence prefix, CharSequence suffix)

入力要素を検出順に指定された区切り文字で区切りながら連結し、指定された接頭辞と接尾辞を付加するCollectorを返します。

final var stream = Stream.of("aaa", "XXX", "bbb", "YYY");

final var ret = stream.collect(Collectors.joining("-", "[", "]"));
System.out.println(ret); // [aaa-XXX-bbb-YYY]

static <T, U, A, R> Collector<T,?,R> mapping (Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream)

U型の要素を受け取るCollectorがT型の要素を受け取れるように適応させるため、各入力要素にマッピング関数を適用した後で蓄積を行うようにします。

record Book(String category, String title, int price) {
}

final var stream = Stream.of(
        new Book("Travel", "aaa", 10),
        new Book("History", "bbb", 20),
        new Book("Cooking", "ccc", 50),
        new Book("Cooking", "ddd", 40),
        new Book("History", "eee", 30)
);

final var ret = stream.collect(
        Collectors.mapping(
                Book::title,
                Collectors.toUnmodifiableList()));

System.out.println(ret); // [aaa, bbb, ccc, ddd, eee]
record Book(String category, String title, int price) {
}

final var stream = Stream.of(
        new Book("Travel", "aaa", 10),
        new Book("History", "bbb", 20),
        new Book("Cooking", "ccc", 50),
        new Book("Cooking", "ddd", 40),
        new Book("History", "eee", 30)
);

final var ret = stream.collect(Collectors.groupingBy(
        Book::category,
        Collectors.mapping(
                Book::title,
                Collectors.toUnmodifiableList())));

// {Travel=[aaa], Cooking=[ccc, ddd], History=[bbb, eee]}
System.out.println(ret);

static <T> Collector<T,?,Optional<T>> maxBy (Comparator<? super T> comparator)

指定されたComparatorに従ってOptional<T>として記述された最大要素を生成するCollectorを返します。

final var stream = Stream.of(1, 100, -200, 50, -30);

final var ret = stream.collect(Collectors.maxBy(Comparator.naturalOrder()));
System.out.println(ret); // Optional[100]
final var stream = Stream.of("Tree", "book", "stone", "Cake");

final var ret = stream.collect(Collectors.maxBy(String.CASE_INSENSITIVE_ORDER));
System.out.println(ret); // Optional[Tree]
final var stream = Stream.<String>empty();

final var ret = stream.collect(Collectors.maxBy(Comparator.naturalOrder()));
System.out.println(ret); // Optional.empty

static <T> Collector<T,?,Optional<T>> minBy (Comparator<? super T> comparator)

指定されたComparatorに従ってOptional<T>として記述された最小要素を生成するCollectorを返します。

final var stream = Stream.of(1, 100, -200, 50, -30);

final var ret = stream.collect(Collectors.minBy(Comparator.naturalOrder()));
System.out.println(ret); // Optional[-200]
final var stream = Stream.of("Tree", "book", "stone", "Cake");

final var ret = stream.collect(Collectors.minBy(String.CASE_INSENSITIVE_ORDER));
System.out.println(ret); // Optional[book]
final var stream = Stream.<String>of();

final var ret = stream.collect(Collectors.minBy(Comparator.naturalOrder()));
System.out.println(ret); // Optional.empty

static <T> Collector<T,?,Map<Boolean,List<T>>> partitioningBy (Predicate<? super T> predicate)

Predicateに従って入力要素を分割し、結果をMap<Boolean, List<T>>内に格納するCollectorを返します。

final var stream = Stream.of(1, 2, 3, 4, 5);

// true = 偶数, false = 奇数
final var ret = stream.collect(
        Collectors.partitioningBy((value) -> value % 2 == 0));

System.out.println(ret); // {false=[1, 3, 5], true=[2, 4]}

static <T, D, A> Collector<T,?,Map<Boolean,D>> partitioningBy (Predicate<? super T> predicate, Collector<? super T,A,D> downstream)

Predicateに従って入力要素を分割し、別のCollectorに従って各パーティションの値をリデュースし、結果をMap<Boolean, D>内に格納するCollectorを返します(下流のリダクションの結果がマップの値になる)。

record Item(Integer value, String name) {
}

final var stream = Stream.of(
        new Item(1, "aaa"),
        new Item(2, "bbb"),
        new Item(3, "ccc"),
        new Item(4, "ddd"),
        new Item(5, "eee")
);

// true = 偶数, false = 奇数
final var ret = stream.collect(
        Collectors.partitioningBy(
                (item) -> item.value() % 2 == 0,
                Collectors.mapping(
                        Item::name,
                        Collectors.toUnmodifiableList()
                )));

System.out.println(ret); // {false=[aaa, ccc, eee], true=[bbb, ddd]}

static <T> Collector<T,?,Optional<T>> reducing (BinaryOperator<T> op)

指定されたBinaryOperatorの下で入力要素のリダクションを実行するCollectorを返します。

record Book(String category, String title, int price) {
}

final var stream = Stream.of(
        new Book("Travel", "aaa", 10),
        new Book("History", "bbb", 20),
        new Book("Cooking", "ccc", 50),
        new Book("Cooking", "ddd", 40),
        new Book("History", "eee", 30)
);

final var comparator = Comparator.comparing(Book::price);

final var map = stream.collect(
        Collectors.groupingBy(
                Book::category,
                Collectors.reducing(
                        BinaryOperator.maxBy(comparator)
                )));

System.out.println("-- entry --");
for (final var entry : map.entrySet()) {
    System.out.println(entry);
}

// 結果
// ↓
//-- entry --
//Travel=Optional[Book[category=Travel, title=aaa, price=10]]
//Cooking=Optional[Book[category=Cooking, title=ccc, price=50]]
//History=Optional[Book[category=History, title=eee, price=30]]

static <T> Collector<T,?,T> reducing (T identity, BinaryOperator<T> op)

指定されたBinaryOperatorの下で指定された単位元を使って入力要素のリダクションを実行するCollectorを返します。

record Book(String category, String title, int price) {
}

final var stream = Stream.of(
        new Book("Travel", "aaa", 10),
        new Book("History", "bbb", 20),
        new Book("Cooking", "ccc", 50),
        new Book("Cooking", "ddd", 40),
        new Book("History", "eee", 30)
);

final var identity = new Book("", "", 0);
final var comparator = Comparator.comparing(Book::price);

final var map = stream.collect(
        Collectors.groupingBy(
                Book::category,
                Collectors.reducing(
                        identity,
                        BinaryOperator.maxBy(comparator)
                )));

System.out.println("-- entry --");
for (final var entry : map.entrySet()) {
    System.out.println(entry);
}

// 結果
// ↓
//-- entry --
//Travel=Book[category=Travel, title=aaa, price=10]
//Cooking=Book[category=Cooking, title=ccc, price=50]
//History=Book[category=History, title=eee, price=30]

static <T, U> Collector<T,?,U> reducing (U identity, Function<? super T,? extends U> mapper, BinaryOperator<U> op)

指定されたマッピング関数とBinaryOperatorの下で入力要素のリダクションを実行するCollectorを返します。

record Book(String category, String title, int price) {
}

final var stream = Stream.of(
        new Book("Travel", "aaa", 10),
        new Book("History", "bbb", 20),
        new Book("Cooking", "ccc", 50),
        new Book("Cooking", "ddd", 40),
        new Book("History", "eee", 30)
);

final var identity = 0;

final var map = stream.collect(
        Collectors.groupingBy(
                Book::category,
                Collectors.reducing(
                        identity,
                        Book::price,
                        BinaryOperator.maxBy(Comparator.naturalOrder())
                )));

System.out.println("-- entry --");
for (final var entry : map.entrySet()) {
    System.out.println(entry);
}

// 結果
// ↓
//-- entry --
//Travel=10
//Cooking=50
//History=30

static <T> Collector<T,?,DoubleSummaryStatistics> summarizingDouble (ToDoubleFunction<? super T> mapper)

各入力要素にdouble生成マッピング関数を適用し、その結果の値のサマリー統計を返すCollectorを返します。

final var stream = Stream.of(1.0, 2.0, 3.0);
final var ret = stream.collect(Collectors.summarizingDouble(value -> value));

// DoubleSummaryStatistics{count=3, sum=6.000000, min=1.000000, average=2.000000, max=3.000000}
System.out.println(ret);

static <T> Collector<T,?,IntSummaryStatistics> summarizingInt (ToIntFunction<? super T> mapper)

各入力要素にint生成マッピング関数を適用し、その結果の値のサマリー統計を返すCollectorを返します。

final var stream = Stream.of(1, 2, 3);
final var ret = stream.collect(Collectors.summarizingInt(value -> value));

// IntSummaryStatistics{count=3, sum=6, min=1, average=2.000000, max=3}
System.out.println(ret);

static <T> Collector<T,?,LongSummaryStatistics> summarizingLong (ToLongFunction<? super T> mapper)

各入力要素にlong生成マッピング関数を適用し、その結果の値のサマリー統計を返すCollectorを返します。

final var stream = Stream.of(10000000000L, 20000000000L, 30000000000L);
final var ret = stream.collect(Collectors.summarizingLong(value -> value));

// LongSummaryStatistics{count=3, sum=60000000000,
//   min=10000000000, average=20000000000.000000, max=30000000000}
System.out.println(ret);

static <T> Collector<T,?,Double> summingDouble (ToDoubleFunction<? super T> mapper)

入力要素に適用されたdouble値関数の合計を生成するCollectorを返します。

final var stream = Stream.of(1.0, 2.0, 3.0);
final var ret = stream.collect(Collectors.summingDouble(value -> value));

System.out.println(ret); // 6.0

static <T> Collector<T,?,Integer> summingInt (ToIntFunction<? super T> mapper)

入力要素に適用された整数値関数の合計を生成するCollectorを返します。

final var stream = Stream.of(1, 2, 3);
final var ret = stream.collect(Collectors.summingInt(value -> value));

System.out.println(ret); // 6

static <T> Collector<T,?,Long> summingLong (ToLongFunction<? super T> mapper)

入力要素に適用されたlong値関数の合計を生成するCollectorを返します。

final var stream = Stream.of(10000000000L, 20000000000L, 30000000000L);
final var ret = stream.collect(Collectors.summingLong(value -> value));

System.out.println(ret); // 60000000000

static <T, R1, R2, R> Collector<T,?,R> teeing (Collector<? super T,?,R1> downstream1, Collector<? super T,?,R2> downstream2, BiFunction<? super R1,? super R2,R> merger)

2つのダウンストリーム・コレクタのコンポジットであるCollectorを返します。

final var stream = Stream.of("aaa", "bbb", "ccc");

final var ret = stream.collect(Collectors.teeing(
        Collectors.joining("-"),
        Collectors.joining("+"),
        (s1, s2) -> "[" + s1 + ", " + s2 + "]"
));

System.out.println(ret); // [aaa-bbb-ccc, aaa+bbb+ccc]

static <T, C extends Collection<T>> Collector<T,?,C> toCollection (Supplier<C> collectionFactory)

入力要素を検出順に新しいCollectionに蓄積するCollectorを返します。

final var stream = Stream.of("aaa", "bbb", "ccc");
final var ret = stream.collect(Collectors.toCollection(LinkedList::new));

System.out.println(ret); // [aaa, bbb, ccc]
System.out.println(ret.getClass()); // class java.util.LinkedList

static <T, K, U> Collector<T,?,ConcurrentMap<K,U>> toConcurrentMap (Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)

ConcurrentMap内に要素を累積する並行Collectorを返します(指定されたマッピング関数を入力要素に適用した結果が、マップのキーと値になる)。

record Item(String name, int value) {
}

final var stream = Stream.of(
        new Item("aaa", 10),
        new Item("bbb", 20),
        new Item("ccc", 30)
);

final var ret = stream.collect(Collectors.toConcurrentMap(
        Item::name, Item::value));

System.out.println(ret); // {aaa=10, ccc=30, bbb=20}

static <T, K, U> Collector<T,?,ConcurrentMap<K,U>> toConcurrentMap (Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)

ConcurrentMap内に要素を累積する並行Collectorを返します(指定されたマッピング関数を入力要素に適用した結果が、マップのキーと値になる)。

record Item(String name, int value) {
}

final var stream = Stream.of(
        new Item("aaa", 1),
        new Item("aaa", 2),
        new Item("bbb", 30),
        new Item("bbb", 40),
        new Item("ccc", 500)
);

final var ret = stream.collect(Collectors.toConcurrentMap(
        Item::name, Item::value, (value1, value2) -> value1 + value2));

System.out.println(ret); // {aaa=3, ccc=500, bbb=70}

static <T, K, U, M extends ConcurrentMap<K, U>> Collector<T,?,M> toConcurrentMap (Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapFactory)

ConcurrentMap内に要素を累積する並行Collectorを返します(指定されたマッピング関数を入力要素に適用した結果が、マップのキーと値になる)。

record Item(String name, int value) {
}

final var stream = Stream.of(
        new Item("aaa", 1),
        new Item("aaa", 2),
        new Item("bbb", 30),
        new Item("bbb", 40),
        new Item("ccc", 500)
);

final var ret = stream.collect(Collectors.toConcurrentMap(
        Item::name, Item::value, (value1, value2) -> value1 + value2,
        ConcurrentSkipListMap::new));

System.out.println(ret); // {aaa=3, bbb=70, ccc=500}
System.out.println(ret.getClass()); // class java.util.concurrent.ConcurrentSkipListMap

static <T> Collector<T,?,List<T>> toList ()

入力要素を新しいListに蓄積するCollectorを返します。

final var stream = Stream.of("aaa", "bbb", "ccc");

final var ret = stream.collect(Collectors.toList());
System.out.println(ret); // [aaa, bbb, ccc]

// 変更可能です。
ret.add("XXX");
System.out.println(ret); // [aaa, bbb, ccc, XXX]

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

Map(そのキーと値は指定されたマッピング関数を入力要素に適用した結果である)内に要素を蓄積するCollectorを返します。

record Item(String name, int value) {
}

final var stream = Stream.of(
        new Item("aaa", 10),
        new Item("bbb", 20),
        new Item("ccc", 30)
);

final var ret = stream.collect(Collectors.toMap(
        Item::name, Item::value));

System.out.println(ret); // {aaa=10, ccc=30, bbb=20}

// 変更可能です。
ret.put("XXX", 999);
System.out.println(ret); // {aaa=10, ccc=30, bbb=20, XXX=999}

static <T, K, U> Collector<T,?,Map<K,U>> toMap (Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)

Map(そのキーと値は指定されたマッピング関数を入力要素に適用した結果である)内に要素を蓄積するCollectorを返します。

record Item(String name, int value) {
}

final var stream = Stream.of(
        new Item("aaa", 1),
        new Item("aaa", 2),
        new Item("bbb", 30),
        new Item("bbb", 40),
        new Item("ccc", 500)
);

final var ret = stream.collect(Collectors.toMap(
        Item::name, Item::value, (value1, value2) -> value1 + value2));

System.out.println(ret); // {aaa=3, ccc=500, bbb=70}

// 変更可能です。
ret.put("XXX", 999);
System.out.println(ret); // {aaa=3, ccc=500, bbb=70, XXX=999}

static <T, K, U, M extends Map<K, U>> Collector<T,?,M> toMap (Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapFactory)

Map(そのキーと値は指定されたマッピング関数を入力要素に適用した結果である)内に要素を蓄積するCollectorを返します。

record Item(String name, int value) {
}

final var stream = Stream.of(
        new Item("aaa", 1),
        new Item("aaa", 2),
        new Item("bbb", 30),
        new Item("bbb", 40),
        new Item("ccc", 500)
);

final var ret = stream.collect(Collectors.toMap(
        Item::name, Item::value, (value1, value2) -> value1 + value2,
        TreeMap::new));

System.out.println(ret); // {aaa=3, bbb=70, ccc=500}
System.out.println(ret.getClass()); // class java.util.TreeMap

static <T> Collector<T,?,Set<T>> toSet ()

入力要素を新しいSetに蓄積するCollectorを返します。

final var stream = Stream.of("aaa", "bbb", "ccc");

final var ret = stream.collect(Collectors.toSet());
System.out.println(ret); // [aaa, ccc, bbb]

// 変更可能です。
ret.add("XXX");
System.out.println(ret); // [aaa, ccc, bbb, XXX]

static <T> Collector<T,?,List<T>> toUnmodifiableList ()

Collectorを返します。これは入力要素を「変更不可能なリスト」に遭遇順序で累積します。

final var stream = Stream.of("aaa", "bbb", "ccc");

final var ret = stream.collect(Collectors.toUnmodifiableList());
System.out.println(ret); // [aaa, bbb, ccc]

ret.add("XXX"); // java.lang.UnsupportedOperationException

static <T, K, U> Collector<T,?,Map<K,U>> toUnmodifiableMap (Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)

入力要素を「変更不可能なマップ」に蓄積するCollectorを返します。そのキーと値は、提供されたマッピング関数を入力要素に適用した結果です。

record Item(String name, int value) {
}

final var stream = Stream.of(
        new Item("aaa", 10),
        new Item("bbb", 20),
        new Item("ccc", 30)
);

final var ret = stream.collect(Collectors.toUnmodifiableMap(
        Item::name, Item::value));

System.out.println(ret); // {aaa=10, ccc=30, bbb=20}

ret.put("XXX", 999); // java.lang.UnsupportedOperationException

static <T, K, U> Collector<T,?,Map<K,U>> toUnmodifiableMap (Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)

入力要素を「変更不可能なマップ」に蓄積するCollectorを返します。そのキーと値は、提供されたマッピング関数を入力要素に適用した結果です。

record Item(String name, int value) {
}

final var stream = Stream.of(
        new Item("aaa", 1),
        new Item("aaa", 2),
        new Item("bbb", 30),
        new Item("bbb", 40),
        new Item("ccc", 500)
);

final var ret = stream.collect(Collectors.toUnmodifiableMap(
        Item::name, Item::value, (value1, value2) -> value1 + value2));

System.out.println(ret); // {aaa=3, ccc=500, bbb=70}

ret.put("XXX", 999); // java.lang.UnsupportedOperationException

static <T> Collector<T,?,Set<T>> toUnmodifiableSet ()

入力要素を「変更不可能なセット」に蓄積するCollectorを返します。

final var stream = Stream.of("aaa", "bbb", "ccc");

final var ret = stream.collect(Collectors.toUnmodifiableSet());
System.out.println(ret); // [aaa, ccc, bbb]

ret.add("XXX"); // java.lang.UnsupportedOperationException

関連記事

ページの先頭へ