倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

蒐集してやんよ java.util.stream.Collectors クラス (3) - 内蔵コレクタの特性 -

Java の Collectors クラスに定義されているメソッドを見ていくシリーズ(目次)。 前回までで java.util.stream.Collectors クラスで取得できる Collector オブジェクトの使い方を見ました。 そこでは基本的な使い方を見ていたので Collector インターフェース自体の API には触れてませんでした。 なので、それらの API を改めて見ていたのですが、コレクタには特性 (characteristics) というプロパティ(?)があるようです:

package java.util.stream;

public interface Collector<T,R>{

    ... // いくつかのメソッド

    Set<Collector.Characteristics> characteristics();

    public static enum Characteristics{
        CONCURRENT,
        STRICTLY_MUTATIVE,
        UNORDERED
    }
}

コレクタの特性は Collector.Characteristics という定数(列挙型)で定義されています。 この定数には(Java 8 ea-b90 では)3つの値が定義されています:

定数 説明
CONCURRENT 並列処理を行う
STRICTLY_MUTATIVE コレクト処理の結果として返す(コンテナ)オブジェクトが可変な(状態を持つ)オブジェクト
UNORDERED コレクト処理の結果に定まった順序を持たない
  • STRICTLY_MUTATIVE は、コレクト結果が StringBuilder, StringJoiner や(可変)コレクション型のような場合に返されます。
  • CONCURRENT はストリームの各要素に対して並行処理を行ってコレクト処理の結果として、その並行処理の結果を含んだ(コンテナ)オブジェクトを返すので STRICTLY_MUTATIVE でもあります。
  • Collectors クラスの static メソッドが返す CONCURRENT のコレクタは UNORDERED でもあるようです。 並行処理を行うと処理順序が不定なので大抵の場合は CONCURRENT なら UNORDERED になるかと。

以上を踏まえて、前回までで見た Collectors クラスの static メソッドが返すコレクタの特性をまとめると下表のようになります:

コレクタ CONCURRENT STRICTLY_MUTATIVE UNORDERED
mapping(mapper, collector)
reducing(op)
reducing(identity, op)
reducing(identity, mapper, op)
toStringBuilder()
toStringJoiner(delim)
   ○
   ○
toCollection()
toList()
toSet()
   ○

   ○


   ○
counting()
sumBy(mapper)
maxBy(comparater)
minBy(comparater)
toIntSummaryStatistics(mapper)
toLongSummaryStatistics(mapper)
toDoubleSummaryStatistics(mapper)
   ○
   ○
   ○
toMap(mapper, mapper)
toMap(mapper, mapper, merger)
toMap(mapper, mapper, merger, factory)
   ○
   ○
   ○
toConcurrentMap(mapper, mapper)
toConcurrentMap(mapper, mapper, merger)
toConcurrentMap(mapper, mapper, merger, factory)
   ○
   ○
   ○
   ○
   ○
   ○
   ○
   ○
   ○
partitioningBy(predicate)
partitioningBy(predicate, collector)
   ○
   ○
groupingBy(classifier)
groupingBy(classifier, collector)
groupingBy(classifier, factory, collector)
   ○
   ○
   ○
groupingByConcurrent(classifier)
groupingByConcurrent(classifier, collector)
groupingByConcurrent(classifier, factory, collector)
   ○
   ○
   ○
   ○
   ○
   ○
   ○
   ○
   ○
  • CONCURRENT 特性を持つメソッドはメソッド名に「Concurrent」が付いているものだけのようです。 それらは STRICTLY_MUTATIVE であり UNORDERED であります。
  • UNORDERED ではあるけど CONCURRENT ではないのは toSet() だけのようです。
  • toList() が STRICTLY_MUTATIVE でないのは?
  • static ファクトリメソッドの引数に別のコレクタを渡して生成するコレクタは、渡すコレクタの特性によってその特性が変化したりしないかちょっと微妙ですが、いくつか試した中では変わりませんでした(そんなにたくさん試したわけではありませんが)。

次回こそ独自コレクタを作ろうか・・・

Scalaスケーラブルプログラミング第2版

Scalaスケーラブルプログラミング第2版