RxJava:マージ()が放出される項目の順序を変更しますか?

フランチェスコ:

これらの2つの小さなテストを行います:

@Test
public void test1() {
    Observable.range(1, 10)
        .groupBy(v -> v % 2 == 0)
        .flatMap(group -> {
            if (group.getKey()) {
                return group;
            }
            return group;
        })
        .subscribe(System.out::println);
}

@Test
public void test2() {
    Observable.range(1, 10)
        .groupBy(v -> v % 2 == 0)
        .toMap(g -> g.getKey())
        .flatMapObservable(m -> Observable.merge(
            m.get(true),
            m.get(false)))
        .subscribe(System.out::println);
}

私は、両方が同じ順序で番号のリストを返すように期待していました。

1 2 3 4 5 6 7 8 9 10

しかし、第2の実施の戻り

2 4 6 8 10 1 3 5 7 9

代わりに。

第二の例にように思わmergeやっているconcat私はそれを変更した場合、実際には、代わりにconcat、結果は同じです。

私は何をしないのですか?

ありがとうございました。

TmTron:

基本的に、flatMapそしてmerge放出された項目の順序を保証するものではありません。

flatMapのドキュメント:

彼らはインターリーブするように、FlatMapは、これらの観測の排出量をマージすることに注意してください。

マージドキュメント:

マージがマージ観測によって放出されたアイテムをインターリーブすることができる(類似演算子、連結方式は、次のソース観測からアイテムを放出し始める前に、インターリーブしないアイテムが、順番にすべての各光源の放射する観測の商品を行います)。

このからの引用SO回答

あなたのケースでは、単一要素、静的な流れと、それは任意の実際の違いを作っていません(ただし、理論的には、マージはまだ出力ランダムな順序での単語とは仕様に応じて有効である可能性があり)

あなたは保証の注文を使用する必要がある場合はconcat*代わりに。

最初の例

それはこのように動作します:

  • 時に1放出されるgroupByオペレータが作成されますGroupedObservableキーでfalse
    • flatMap この観測可能の意志の出力項目 - 唯一の現在 1
  • 時に2放出されるgroupByオペレータが作成されますGroupedObservableキーでtrue
    • flatMap今も意志、この第二の出力項目をGroupedObservable-現在2
  • 時に3放出されているgroupByオペレータは、既存に追加しますGroupedObservableキーとfalseし、flatMapすぐに意志を出力こちら
  • 時に4放出されているgroupByオペレータは、既存に追加しますGroupedObservableキーとtrueし、flatMapすぐに意志を出力こちら

それはあなたには、いくつかのより多くのログを追加するのに役立つことがあります。

    Observable.range(1, 10)
            .groupBy(v -> v % 2 == 0)
            .doOnNext(group -> System.out.println("key: " + group.getKey()))
            .flatMap(group -> {
                if (group.getKey()) {
                    return group;
                }
                return group;
            })
            .subscribe(System.out::println);

その後、出力は次のようになります。

key: false
1
key: true
2
3
...

第二の例

これは、かなり異なっているtoMap上流完了するまでブロックされます:

  • 時に1放出されるgroupByオペレータが作成されますGroupedObservableキーでfalse
    • toMapこれを追加するGroupedObservable内部マップに、キーを使用していますfalse(同じキーとしてGroupedObservable持っています)
  • 時に2放出されるgroupByオペレータが作成されますGroupedObservableキーでtrue
    • toMapこれを追加するGroupedObservable内部マップに、キー使用していますtrue(同じキーGroupedObservableがある)を-だから今のマップには2を持っていますGroupedObservables
  • 次の番号は、対応するに追加されGroupedObservables、ソース完了toMapオペレータが行われ、次の演算子にマップを通過します
  • flatMapObservable、あなたが最初の偶数の要素(キー=を追加する場所に新しい観測可能作成するためにマップを使用true)し、その後奇数の要素(キー= false

また、ここでは、いくつかのより多くのログを追加することができます。

    Observable.range(1, 10)
            .groupBy(v -> v % 2 == 0)
            .doOnNext(group -> System.out.println("key: " + group.getKey()))
            .toMap(g -> g.getKey())
            .doOnSuccess(map -> System.out.println("map: " + map.size()))
            .flatMapObservable(m -> Observable.merge(
                    m.get(true),
                    m.get(false)
            ))
            .subscribe(System.out::println);

その後、出力は次のようになります。

key: false
key: true
map: 2
2
4
6
8
10
1
3
5
7
9

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=213645&siteId=1