Optional
*のプリミティブバージョンとして、Java 1.8は OptionalInt
、 OptionalLong
および OptionalDouble
。
しかし、同等のOptionalBoolean
クラスが見つかりません。
OptionalBoolean
を使用することに技術的な理由はありますか?
*Optional
は、値の存在の有無にかかわらず、null
の代わりに使用されます。
この引用は、プリミティブストリームの背後にある考慮事項を説明しています。私はプリミティブオプションにも同じことが適用されると想定しています。つまり、パフォーマンス上の理由から、プリミティブストリーム(およびおそらくオプション)が作成されました。コードの重複とインターフェイスの汚染を減らすために、8つのプリミティブタイプすべてに対してそれらを作成していません。
lambdaメーリングリスト でブライアン・ゲッツの言葉を引用する:
より一般的には、特殊なプリミティブストリーム(IntStreamなど)の背後にある哲学には、厄介なトレードオフが伴います。一方で、コードの重複、インターフェイスの汚染など、多くの醜いコードです。他方、ボックス化されたopsでのあらゆる種類の演算は失敗し、intを削減するためのストーリーがないのはひどいでしょう。だから私たちは厳しい状況にあり、それを悪化させないように努めています。
悪化させないための秘訣1は、8つのプリミティブ型すべてを実行していないことです。 int、long、doubleを実行しています。他のすべてはこれらによってシミュレートできます。おそらくintも取り除くことができますが、ほとんどの場合Java開発者はその準備ができていないと思います。はい、Characterの呼び出しがあり、答えは「 int。」(各専門分野は、JREフットプリントに対して〜100Kと予測されています。)
トリック#2は、プリミティブストリームを使用して、プリミティブドメイン(ソート、リダクション)で最適に行われることを公開していますが、ボックス化ドメインで実行できるすべてを複製しようとはしていません。たとえば、Alekseyが指摘するように、IntStream.into()はありません。 (ある場合、次の質問は「IntCollectionはどこですか?IntArrayList?IntConcurrentSkipListMap?」でしょう。)多くのストリームが参照ストリームとして開始し、プリミティブストリームとして終了する可能性がありますが、その逆ではありません。それは問題ありません。必要な変換の数を減らします(たとえば、int-> Tのマップのオーバーロードなし、int-> Tの関数の特殊化なしなど)
そして、私はその引用が この質問 の回答で見つかったことを言及する必要があります。
boolean
値は、パラメーターとして悪用されることがよくあります。効果的なJava第2版はブール値の悪用を警告します。実際のブール値のtrue/false引数でないと、コードが読みにくくなる可能性があります。代わりに、作家のJoshua Blochが人々を説得しようとします二重値のenum
を使用するには:
enum
パラメータよりも2要素のboolean
タイプを優先する。特に、オートコンプリートをサポートするIDEを使用している場合は特に、コードの読み書きが容易になります。また、後でオプションを追加するのも簡単になります。
ほとんどのOptionalBoolean
インスタンスはおそらく正しく使用されません。これが含まれていないことの正当な理由です。しかし、これがOracleに存在しない理由である場合、Oracleだけが可能であるとは言えません。
プリミティブ型特殊化クラスの組み合わせ爆発の規模を減らしたいという欲求は別として、OptionalBoolean
が存在しない主な理由の1つは、そのようなクラスの利点が、特殊化の利点よりもはるかに小さいことです。数値型。
利点が小さい理由は、型boolean
の値が2つしかないためです。このため、ほとんどの場合、Boolean
タイプの2つのオブジェクトしか取得できません。これら2つはBoolean.TRUE
およびBoolean.FALSE
としてキャッシュされ、ほとんどの場合再利用されます。 boolean
sが自動ボックス化されている場合。数値ラッパータイプには、値の範囲が狭いためにキャッシュされたオブジェクトがいくつかあります。他の値については、プリミティブ値がOptional
などの汎用コンテナーに格納されるたびに新しいオブジェクトを割り当てる必要があります。
したがって、ボックス化されていないOptionalBoolean
を配置するために新しいBoolean
を割り当てる必要がないため、Optional<Boolean>
オブジェクトはboolean
とほぼ同じくらい効率的です。
また、おそらくOptional<Boolean>
のように、標準ライブラリのどこかにキャッシュされた2つのOptional.TRUE/FALSE
を用意しておくと便利です。存在しない理由がわかりません。
ちょうどそれについて完全にするために:Java 8には確かにOptionalBoolean
がありますが、期待する場所ではありません:com.Sun.javafx.scene.control.behavior.OptionalBoolean
です。
しかし、JavaFXは現在、Javaの固定コンポーネントですが、JavaFX以外で使用することはお勧めできません。
それとは別に、そのインターフェースはJava.util.*
にあるものとは完全に異なります。