2017-02-13 21 views
10

私はリストを作成するメソッドを持っています。リストの平均をオプション値として返すことができます。Optional Optional Double to Optional <java.lang.Double>

しかし、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(); 
} 

感謝。

+2

OptionalDoubleの 'getAsDouble'では、' double'の平均値が得られます。これは最終的に何が必要なのでしょうか。 – VHS

+3

OptionalDoubleがより効率的です。 'double'に近いので、使用コードを' Optional 'から' OptionalDouble'に変換する方が良いでしょう。しかし、私はあなたがそれを知っていると思うし、あなたの理由があると思う。 –

+2

コードがリストのようにビルドされている場合は、すでに空ではないことがわかります。だからなぜ「オプション」を返すのですか? – Holger

答えて

1

きちんと解決策が存在するかどうかは知りませんが、THSは動作するはずです:

OptionalDouble optionalDouble = testList.stream().mapToDouble(value -> value).average(); 
return Optional.ofNullable(optionalDouble.isPresent() ? optionalDouble.getAsDouble() : null); 
1

楽しみのためだけに、私はそれがを必要とせず、単一の文で書かれていても大丈夫かどうかを確認したかったですOptionalDouble temp変数です。もしあれば、ちょうどミニマリズムのために、ところで

return ((Function<OptionalDouble, Optional<Double>>) od 
      -> od.isPresent() ? Optional.of(od.getAsDouble()) : Optional.empty()) 
      .apply(testList.stream().mapToDouble(v -> v).average()); 

:私は、この「1行」(単一の文)を溶液に来た

return testList.stream().collect(Collectors.collectingAndThen(
    Collectors.summarizingDouble(Double::doubleValue), 
    stat -> Optional.ofNullable(stat.getCount()>0 ? stat.getAverage() : null))); 
1

:ここで私が思いついた最善の方法ですあなたはそれが少し少ない厄介作るものOptional.を、省略することができ

import static java.util.Optional.*; 

:静的インポートを実行します。

6

私はこのアプローチのために行くだろう:

private static Optional<Double> convert(OptionalDouble od) 
{ 
    return od.isPresent() ? 
     Optional.of(od.getAsDouble()) : Optional.empty(); 
} 
4

ところで、私は最も単純な形式を持っている別の解決策を見つけました。

私は考え始めました:いつ平均の結果が空になることができますか?それが自分自身が空の場合にのみ、右か?私たちは確信しているのであれば、私たちが安全にgetAsDouble()を行うことができますよりも、そのリストは、空ではありません。

return Optional.ofNullable(testList.isEmpty() ? null : 
     testList.stream().mapToDouble(v -> v).average().getAsDouble()) 

(同様の答えで提案されたようにパフォーマンスの観点から、これは、追加のラムダラッパーを作成するよりも効率的である可能性があります。)

+3

これは二重テストの最初の 'isEmpty()'、 'ofNullable'の'ヌル 'テストです。 2番目のテストは必要ありません: 'return testList.isEmpty()? – Holger

+3

私はそれについて考えましたが、具体的には、オプションの内部に3値演算を入れました(オプション)。オプション(テストリスト。ストリーム(mapToDouble(v - > v).average()。getAsDouble ofNullable'よりスタイリッシュなものですが、もう1つの比較操作があることに同意します – Andremoniy

4

@Andremoniy's answerに若干のばらつきがDoubleStreamをスキップしてaveragingDouble()コレクタを使用することです:

if (testList.isEmpty()) { 
    return Optional.empty(); 
} 
return Optional.of(testList.stream().collect(Collector.averagingDouble())); 

それとも0が空のリストのための有効な戻り値であり、pかどうかを検討間違いなくOptionalをスキップしてください。

関連する問題