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());
}
コンソールにのみ出力します4
。StringBuilder
オブジェクトは、まだ価値があります""
。
私は、フィルタ操作を追加する場合: 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()
、非干渉、ステートレス操作することになったが、それはステートレスではないです:ドキュメントで定義された契約に違反します。両方の場合で異なる結果を持つので、バグとみなすことはできません。