中級ストリーム操作数に評価されません

atalantus:

私がJavaがストリームパイプラインにストリーム操作を構成する方法、トラブルの理解を抱えているようです。

次のコードを実行するとき

public
 static void main(String[] args) {
    StringBuilder sb = new StringBuilder();

    var count = Stream.of(new String[]{"1", "2", "3", "4"})
            .map(sb::append)
            .count();

    System.out.println(count);
    System.out.println(sb.toString());
}

コンソールにのみ出力します4StringBuilderオブジェクトは、まだ価値があります""

私は、フィルタ操作を追加する場合: filter(s -> true)

public static void main(String[] args) {
    StringBuilder sb = new StringBuilder();

    var count = Stream.of(new String[]{"1", "2", "3", "4"})
            .filter(s -> true)
            .map(sb::append)
            .count();

    System.out.println(count);
    System.out.println(sb.toString());
}

出力は変わります。

4
1234

どのようにこの一見冗長フィルタ操作は、構成ストリームパイプラインの動作を変更しますか?

JB Nizet:

count()端末操作は、JDKの私のバージョンでは、次のコードを実行して終わります。

if (StreamOpFlag.SIZED.isKnown(helper.getStreamAndOpFlags()))
    return spliterator.getExactSizeIfKnown();
return super.evaluateSequential(helper, spliterator);

存在する場合filter()の動作のパイプラインの動作は(以降、最初に知られているストリームのサイズは、もはや知ることができないfilterストリームのいくつかの要素を拒絶することができます)。ようにifブロックが実行されていない、中間の操作が実行され、StringBuilderのは、このように修正されます。

あなたが唯一持っている場合は一方で、map()パイプラインでは、ストリーム内の要素の数は、要素の最初の数と同じであることが保証されます。もしそうであれば、ブロックが実行され、サイズが中間操作を評価せずに直接戻されます。

ラムダに渡されたことに注意してくださいmap()、非干渉、ステートレス操作することになったが、それはステートレスではないです:ドキュメントで定義された契約に違反します。両方の場合で異なる結果を持つので、バグとみなすことはできません。

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=422986&siteId=1