1. ホーム
  2. java

[解決済み] java 8で型変換を行うreduceメソッドにcombinerが必要な理由

2022-04-14 01:26:59

質問

が果たす役割を十分に理解することができず、困っています。 combiner ストリームで果たす役割 reduce メソッドを使用します。

例えば、次のようなコードはコンパイルできません。

int length = asList("str1", "str2").stream()
            .reduce(0, (accumulatedInt, str) -> accumulatedInt + str.length());

コンパイルエラーで : (引数の不一致; int は java.lang.String に変換できません)

が、このコードはコンパイルできます。

int length = asList("str1", "str2").stream()  
    .reduce(0, (accumulatedInt, str ) -> accumulatedInt + str.length(), 
                (accumulatedInt, accumulatedInt2) -> accumulatedInt + accumulatedInt2);

コンバイナーメソッドは並列ストリームで使用されると理解しています。したがって、私の例では、2つの中間蓄積intを加算しています。

しかし、なぜ最初の例がコンバイナーなしでコンパイルできないのか、また、コンバイナーは2つのintを足し合わせているだけなので、stringからintへの変換をどのように解決しているのか理解できません。

どなたか教えてください。

解決方法は?

の2引数バージョンと3引数バージョンは reduce には同じ型を受け付けません。 accumulator .

2つの引数 reduce と定義されています。 :

T reduce(T identity,
         BinaryOperator<T> accumulator)

あなたの場合、TはStringなので BinaryOperator<T> は2つのString引数を受け取り、Stringを返すはずです。しかし、あなたはintとStringを渡したので、コンパイルエラーが発生しました。 argument mismatch; int cannot be converted to java.lang.String . 実は、ID値として0を渡すのも間違っていると思います。

また、このバージョンのreduceはTsのストリームを処理してTを返すので、Stringのストリームをintにリデュースするのには使えないことに注意してください。

3つの引数 reduce と定義されています。 :

<U> U reduce(U identity,
             BiFunction<U,? super T,U> accumulator,
             BinaryOperator<U> combiner)

あなたの場合、UはInteger、TはStringなので、このメソッドはStringのストリームをIntegerに縮小します。

については BiFunction<U,? super T,U> アキュムレータは、2つの異なる型(U と ? super T)のパラメータを渡すことができ、あなたの場合は、Integer と String です。また、ID値Uは、あなたの場合、Integerを受け取りますので、0を渡しても問題ありません。

あなたが望むことを実現するもう1つの方法.

int length = asList("str1", "str2").stream().mapToInt (s -> s.length())
            .reduce(0, (accumulatedInt, len) -> accumulatedInt + len);

ここでは、ストリームの型は reduce の2パラメータ版を使用することができます。 reduce .

もちろん reduce を全く使わない。

int length = asList("str1", "str2").stream().mapToInt (s -> s.length())
            .sum();