Concat VS Оператор слияния
Я проверял документацию RXJava, и я замечаю, что операторы concat и merge, похоже, делают то же самое. Я написал пару тестов, чтобы быть уверенным.
@Test
public void testContact() {
Observable.concat(Observable.just("Hello"),
Observable.just("reactive"),
Observable.just("world"))
.subscribe(System.out::println);
}
@Test
public void testMerge() {
Observable.merge(Observable.just("Hello"),
Observable.just("reactive"),
Observable.just("world"))
.subscribe(System.out::println);
}
В документации говорится:
Оператор Merge также схож. Он объединяет выбросы двух или более наблюдаемых, но может чередовать их, тогда как Concat никогда не смешивает выбросы от нескольких Observables.
Но все-таки я не понимаю, запустив этот тест тысячу раз, результат слияния всегда один и тот же. Поскольку заказ не предоставляется, я ожидал иногда "реактивный" "мир", например, "привет".
Код находится здесь https://github.com/politrons/reactive
Ответы
Ответ 1
Это описано в документации, которую вы указали. Объединение может чередовать выходы, в то время как concat сначала ожидает завершения более ранних потоков до обработки последующих потоков. В вашем случае с одноэлементными статическими потоками это не имеет никакого реального значения (но теоретически слияние может выводить слова в произвольном порядке и по-прежнему действовать в соответствии со спецификацией). Если вы хотите увидеть разницу, попробуйте сделать следующее (вам нужно будет потом немного поспать, чтобы избежать раннего выхода)
Observable.merge(
Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
.subscribe(System.out::println);
A0 B0 A1 B1 B2 A2 B3 A3 B4 A4
против
Observable.concat(
Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
.subscribe(System.out::println);
A0 A1 A2 A3 A4 A5 A6 A7 A8
Concat никогда не начнет печатать B, потому что поток A никогда не заканчивается.
s/поток/наблюдаемый /g;)
Документация дает хорошие графики, чтобы показать разницу. Вы должны помнить, что слияние не дает никаких гарантий чередования элементов один за другим, это всего лишь один из возможных примеров.
Concat
Слияние
Ответ 2
Concat
Concat испускает выбросы от двух или более Observables, не чередуя их. Это будет поддерживать порядок наблюдаемых во время испускания предметов. Это означает, что он будет излучать все элементы первой наблюдаемой, а затем будет излучать все элементы второй наблюдаемой и так далее.
Позвольте понять это на примере.
final String[] listFirst = {"A1", "A2", "A3", "A4"};
final String[] listSecond = {"B1", "B2", "B3"};
final Observable<String> observableFirst = Observable.fromArray(listFirst);
final Observable<String> observableSecond = Observable.fromArray(listSecond);
Observable.concat(observableFirst, observableSecond)
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String value) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
Поскольку мы используем Concat Operator, он будет поддерживать порядок и выдавать значения как A1, A2, A3, A4, B1, B2, B3.
сливаться
Слияние объединяет несколько наблюдаемых в одну, объединяя их выбросы. Он не будет поддерживать порядок при выделении предметов.
Позвольте понять это на примере.
final String[] listFirst = {"A1", "A2", "A3", "A4"};
final String[] listSecond = {"B1", "B2", "B3"};
final Observable<String> observableFirst = Observable.fromArray(listFirst);
final Observable<String> observableSecond = Observable.fromArray(listSecond);
Observable.merge(observableFirst, observableSecond)
.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(String value) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
Поскольку мы используем оператор слияния, он не будет поддерживать порядок и может выдавать значения в любом порядке, например, A1, B1, A2, A3, B2, B3, A4 или A1, A2, B1, B2, A3, A4, B3. или может быть что угодно.
Вот как мы должны использовать операторы Concat и Merge в RxJava в зависимости от нашего варианта использования.