リストを作成するメソッドがあり、リストの平均をオプションの値として返すようにしたい。
ただし、Java 8を使用して平均値を計算すると、常に戻り値がOptionalDoubleとして取得されます。
変換するにはどうすればよいですか
OptionalDouble to Optional<Double>?
以下は平均計算のための私のコードです:
private static Optional<Double> averageListValue() {
// Build list
List<Double> testList = new ArrayList<>();
testList.add(...);
...
...
return testList.stream().mapToDouble(value -> value).average();
}
ありがとう。
私はこのアプローチを選びます:
private static Optional<Double> convert(OptionalDouble od)
{
return od.isPresent() ?
Optional.of(od.getAsDouble()) : Optional.empty();
}
@ Andremoniyの回答 のわずかなバリエーションは、DoubleStream
をスキップし、averagingDouble()
コレクターを使用することです。
if (testList.isEmpty()) {
return Optional.empty();
}
return Optional.of(testList.stream().collect(Collector.averagingDouble()));
または、0が空のリストの有効な戻り値であるかどうかを検討し、場合によってはOptional
を完全にスキップします。
ところで、私は最も単純な形を持つ別の解決策を見つけました。
私は考え始めました:平均の結果がいつ空になることができるか?リスト自体が空の場合のみですよね?したがって、リストが空でないことが確実な場合は、getAsDouble()
を安全に実行できます。
return Optional.ofNullable(testList.isEmpty() ? null :
testList.stream().mapToDouble(v -> v).average().getAsDouble())
(パフォーマンスの観点から、これは、同様の回答で示唆されているように、追加のラムダラッパーを作成するよりも効率的である可能性があります。)
きちんとした解決策があるかどうかはわかりませんが、これはうまくいくはずです:
OptionalDouble optionalDouble = testList.stream().mapToDouble(value -> value).average();
return Optional.ofNullable(optionalDouble.isPresent() ? optionalDouble.getAsDouble() : null);
楽しみのために、OptionalDouble一時変数を必要とせずに、単一のステートメントで記述できるかどうかを確認したかったのです。これが私が思いついた最高のものです:
return testList.stream().collect(Collectors.collectingAndThen(
Collectors.summarizingDouble(Double::doubleValue),
stat -> Optional.ofNullable(stat.getCount()>0 ? stat.getAverage() : null)));
私はこの「1行」(単一ステートメント)ソリューションに到達しました:
return ((Function<OptionalDouble, Optional<Double>>) od
-> od.isPresent() ? Optional.of(od.getAsDouble()) : Optional.empty())
.apply(testList.stream().mapToDouble(v -> v).average());
ところで、ミニマリズムのために、静的インポートを行う場合は次のようにします。
import static Java.util.Optional.*;
Optional.
を省略できます。これにより、少し面倒になります。