Java 8 stream what 最良の方法を使用してList<Integer>
入力整数の出力がない場合
単にnullを返しますか?しかし今、私の出力リストのサイズは私の入力サイズよりも小さくなります...
List<Integer> input = Arrays.asList(0,1,2,3);
List<Integer> output = input.stream()
.map(i -> {
Integer out = crazyFunction(i);
if(out == null || out.equals(0))
return null;
return Optional.of(out);
})
.collect(Collectors.toList());
なぜあなた(そしてすべての答え)がそんなに複雑にしているのかわかりません。マッピング操作とフィルター操作があります。したがって、最も簡単な方法は、これらの操作を次々に適用することです。また、メソッドが既にOptional
を返さない限り、Optional
を処理する必要はありません。
input.stream().map(i -> crazyFunction(i))
.filter(out -> out!=null && !out.equals(0))
.collect(Collectors.toList());
に簡略化されることがあります
input.stream().map(context::crazyFunction)
.filter(out -> out!=null && !out.equals(0))
.collect(Collectors.toList());
しかし、どの種類のList
を生成するかについて、より理論的な質問があるようです。1つは、値がない場合のプレースホルダーを使用するもの、もう1つは入力リストとは異なるサイズを使用するものです。
簡単な答えは:リストを生成しないです。 List
はそれ自体が目的ではないため、どのようなoperationこのリスト(またはその内容)が必要かを考慮し、ストリームの端末操作として操作権を適用する必要があります。 。次に、存在しない値を除外するか、特別な値で表すか(および必要な値)を操作で指定するので、答えが得られます。
異なる操作に対して異なる答えになるかもしれません…
map
呼び出しをflatMap
に置き換えます。 map
操作は、入力値ごとに1つの出力値を生成しますが、flatMap
操作は、入力値ごとに任意の数の出力値を生成します(ゼロを含む)。
最も簡単な方法は、おそらく次のようにチェックを置き換えることです。
List<Integer> output = input.stream()
.flatMap(i -> {
Integer out = crazyFunction(i);
if (out == null || out.equals(0))
return Stream.empty();
else
return Stream.of(out);
})
.collect(Collectors.toList());
さらにリファクタリングすると、crazyFunction
(おそらくOptional
)を返すようにOptionalInt
を変更できます。 map
から呼び出すと、結果はStream<OptionalInt>
。次に、空のオプションを削除するために、そのストリームをflatMap
する必要があります。
List<Integer> output = input.stream()
.map(this::crazyFunctionReturningOptionalInt)
.flatMap(o -> o.isPresent() ? Stream.of(o.getAsInt()) : Stream.empty())
.collect(toList());
flatMap
の結果はStream<Integer>
はint
sを囲みますが、List
に送信するので問題ありません。 int
の値をList
にボックス化しない場合は、Stream<OptionalInt>
をIntStream
に、次を使用して:
flatMapToInt(o -> o.isPresent() ? IntStream.of(o.getAsInt()) : IntStream.empty())
オプションのストリームの処理の詳細については、 この質問とその回答 を参照してください。
@Martin Magakianの答えのより単純なバリアント:
List<Integer> input = Arrays.asList(0,1,2,3);
List<Optional<Integer>> output =
input.stream()
.map(i -> crazyFunction(i)) // you can also use a method reference here
.map(Optional::ofNullable) // returns empty optional
// if original value is null
.map(optional -> optional.filter(out -> !out.equals(0))) // return empty optional
// if captured value is zero
.collect(Collectors.toList())
;
List<Integer> outputClean =
output.stream()
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList())
;
出力を オプション にラップできます。この値には、null以外の値が含まれる場合と含まれない場合があります。
出力あり:return Optional.of(out);
出力なし:return Optional.<Integer>empty();
配列にはnull値を含めることができないため、オプションにラップする必要があります。
_ List<Integer> input = Arrays.asList(0,1,2,3);
List<Option<Integer>> output = input.stream()
.map(i -> {
Integer out = crazyFunction(i);
if(out == null || out.equals(0))
return Optional.<Integer>empty();
return Optional.of(out);
})
.collect(Collectors.toList());
_
これにより、input.size() == output.size()
が確認されます。
後で、次を使用して空のオプションを除外できます。
_ List<Integer> outputClean = output.stream()
.filter(Optional::isPresent)
.map(i -> {
return i.get();
})
.collect(Collectors.toList());
_