web-dev-qa-db-ja.com

rxjava2のMaybeとOptionalの違いは何ですか?

医師は言う

概念的には、0か1のアイテムが存在する可能性のある放出パターン、または何らかの反応源によって通知されるエラーが発生する可能性のある放出パターンをキャプチャする手段を提供する、シングルとコンプリータブルの結合です。

しかし、それが本当に何を意味するのかはわかりません。 Java8のOptionalのようです。

次の2つのコードの結果は同じですが、Maybeで何ができるのか、Optionalではできない(または扱いにくい)かわかりません。

  @Test
  public void testMaybe1() {
    Observable.just(3, 2, 1, 0, -1)
      .map(i -> {
        try {
          int result = 6 / i;
          return Maybe.just(result);
        } catch (Exception e) {
          return Maybe.empty();
        }
      })
      .blockingForEach(maybe -> {
          logger.info("result = {}", maybe.blockingGet());
        }
      );
  }


  @Test
  public void testMaybe2() {
    Observable.just(3, 2, 1, 0, -1)
      .map(i -> {
        try {
          int result = 6 / i;
          return Optional.of(result);
        } catch (Exception e) {
          return Optional.empty();
        }
      })
      .blockingForEach(opt -> {
          logger.info("result = {}", opt.orElse(null));
        }
      );
  }

結果は同じです:

result = 2
result = 3
result = 6
result = null
result = -6

RxJava1では、私のAPIはObservable<Optional<T>>を返していましたが、悪臭ですか? Observable<Maybe<T>>に変更する必要がありますか?

11
smallufo

Maybeoperation/eventのラッパーです。

  1. 単一の結果
  2. 検索結果はありません
  3. エラー結果

ただし、Optionalはvalueのラッパーです。

  1. プレゼント
  2. 欠席

あなたの例では、map操作では、計算は同期的であり(つまり、_6/i_は同期的であり、すぐに値が生じる可能性があります)、値を伝達したい場合(除算が可能な場合)または空値(除算が不可能な場合)。したがって、Optionalを使用する方が理にかなっています。

ただし、他のオプションもあります。

  • 除算が不可能である理由を伝えたい場合は、発生した例外を報告する必要があります。そのような場合、Maybeを使用する方が理にかなっています。
  • 空の値とエラーの理由の両方に関心がない場合は、単にそれらの結果の伝播をスキップしたいだけです。このようなシナリオでは、flatMapの代わりにmapを使用します。その後、OptionalまたはMaybeを使用する必要はありません。

    _.flatMap(i -> { 
      try { 
        int result = 6 / i; 
        return Observable.just(result); 
      } catch (Exception e) { 
        return Observable.empty(); 
      } 
    }) 
    _

Maybeは、複数の値を出力できるObservableがあるが、たとえば最初の値のみに関心があるため、firstElement()演算子を使用する場合にも役立ちます。観察可能。これは、単一の値があるか、値がない(ソースのObservableが完了する前に値を発行しない場合)か、エラー(ソースのObservableが値を発行する前にエラーの場合)のいずれかである可能性があります。

20
Praveer Gupta

Maybeは、ゼロまたは1つのレイジーストリームです(ストリームになるとエラーが発生する可能性があります)。 Optionalは怠惰ではなく、存在するか存在しないかのどちらかです。 Optionalを使用する場合とは異なり、Maybeを使用した場合の遅延計算の意味はありません。

9
Dave Moten

あなたの質問に関連する違いは、Maybeがエラーを伝搬できる一方で、Optionalはエラーを伝搬できないことです。この例では、エラーと空の結果を区別できません。エラー処理が重要な場合、Optionalは無意味ですが、MaybeにはMaybe.error(Throwable)があります。 API的には、ユースケースではSingleよりもMaybeを優先します。エラーまたは単一の結果が生成されるため、戻り値の型はObservable<Single<T>>

4
m.ostroverkhov

RxJava 2ターゲットJava 6.これは、組み込みのOptionalサポートが保証されていないことを意味し、独自に用意する必要があります。独自のFunction types。

アプリケーション/ライブラリがJava> = 8のみをサポートする場合は、より適切なものを使用できます。

1
Matthias247