2016-01-11 18 views
7

Optional私はOptionalIntに「変換」したいが、これを行う簡単な方法はないようだ。オプションからのオプション取得

public OptionalInt getInt() { 
    return Optional.ofNullable(someString).filter(s -> s.matches("\\d+")).mapToInt(Integer::parseInt); 
} 

しかしOptionalにはmapToInt()方法はありません。

は、ここで私は(不自然な例を)何をしたいのです。

return Optional.ofNullable(someString) 
    .filter(s -> s.matches("\\d+")) 
    .map(s -> OptionalInt.of(Integer.parseInt(s))) 
    .orElse(OptionalInt.empty()); 

が、それは洗練ようだ:

私が思い付くことが最高です。

私はJDKから変換をよりエレガントにすることができるものがありませんか?

答えて

5

コードは、通常の条件式よりも読みやすいものではないが、簡単な解決策があります。Java 9で

public OptionalInt getInt() { 
    return Stream.of(someString).filter(s -> s != null && s.matches("\\d+")) 
     .mapToInt(Integer::parseInt).findAny(); 
} 

は、あなたが言ったように

public OptionalInt getInt() { 
    return Stream.ofNullable(someString).filter(s -> s.matches("\\d+")) 
     .mapToInt(Integer::parseInt).findAny(); 
} 

を使用することができますどちらも一般的な条件式より読みやすいものではありませんが、それでもmapOrElseGetを使用したほうがよく見えます(最初の亜種にはJava 9は必要ありません)。

+0

これはきちんとした考えです。また、私の悪いの 'の'対 'Nullable()' :.私はこの例を単純化しました。これは 'Optional.ofNullable()'だったはずです。私はQを更新し、それに従ってあなたの答えを剪定しました。 – Bohemian

2

いいえ、標準的なJava APIを使用してより洗練された方法で行う方法はありません。そして、私が知る限り、JDK-9でそのようなメソッドを追加する予定はありません。私は、など、mapToInt追加についてhereのポール・サンドを尋ねた彼の答え:

ミー:

が道 がmapToIntようOptional型の間で転送することも提供することをお勧めそれはありませんが、 mapToObjなど、 Stream APIで行われているようですか?

ポール:

私はしたくはあり行っていない、私の応答は*StreamOptional*を変換です。 mapOrElseGetを追加する引数(プリミティブバリアントがUを返すことに注意)は、他の機能をそこから作成できることです。

だから、おそらくJavaの-9に持っているだろう。

return Optional.of(someString).filter(s -> s.matches("\\d+")) 
    .mapOrElseGet(s -> OptionalInt.of(Integer.parseInt(s)), OptionalInt::empty); 

しかし、何よりも。

これは、Optionalクラスとそのプリミティブフレンド(特にプリミティブフレンド)が広く使用されるべきではないことをJDKの著者が主張しているからです。これは、メソッドの戻り値に対して "値の不在 "を意味する。また、プリミティブオプションはパフォーマンス向上のために設計されていますが、実際にはストリームよりもはるかに重要ではないので、Optional<Integer>を使用しても問題ありません。 Valhallaプロジェクト(うまくいけばJava-10に到着予定)では、Optional<int>OptionalIntを使用することができなくなります。それを行うには良い方法あなたの特定のケースで

は三項演算子を使用している:

return someString != null && someString.matches("\\d+") ? 
     OptionalInt.of(Integer.parseInt(someString)) : OptionalInt.empty(); 

私は仮定し、あなたがメソッドからOptionalIntを返すようにしたいということ。それ以外の場合は、なぜあなたがそれを必要とするのかさらに疑問に思う。

+0

私はできるだけ単純な例を作ったが、私はそれが '== nullのように単純ではないと述べている必要があります'test - 私はそこに' filter() 'も持っています。そして、はい、私はそれをメソッドから戻しています。 Q – Bohemian

+1

@Bohemianを更新し、答えを更新します。 Java 1.0のコンストラクトではできない 'Optional'クラスには何もありません。 –

+0

再度、フィルタの例は工夫されています - 私はSSCCEをそのまま使用しようとしました。私のユースケースは、三元がうまくいくほど単純ではありません。私はあなたに諺の葉巻を与えるでしょう:) – Bohemian

1

あなたが任意のオブジェクトだけでなくStringを持っている場合は、一時的にStreamを通過することができます。

public static <T> OptionalInt toOptionalInt(Optional<T> optional, ToIntFunction<? super T> func) { 
    return optional.map(Stream::of).orElseGet(Stream::empty) 
    .mapToInt(func) 
    .findFirst(); 
} 

このソリューションを使用すると、ペースト/の内容をコピーすることができることを意味し、ワンライナーであるという利点を持っているが方法を変更してほしいものをfuncに変更してください。欠点は、あなたが望むものを達成するためにStreamを通過することです。しかし、一般的な1ライナーが必要な場合は、これがそれです。

あなたはユーティリティメソッドをしたい場合、あなたはおそらく次のように使用することを好む:

public static <T> OptionalInt toOptionalInt(Optional<T> optional, ToIntFunction<? super T> func) { 
    if (optional.isPresent()) { 
    return OptionalInt.of(func.applyAsInt(optional.get())); 
    } else { 
    return OptionalInt.empty(); 
    } 
} 
+0

この回答は、タイトルが尋ねるように他の回答が「オプション」から来ていないので、1つを構成し、私が取らないタイトル質問でいくつかの自由を取るので、存在します。 –

関連する問題