2015-03-03 3 views
6

Попытка понять все, что RxJava. Я делал следующий пример:Android RxJava joining lists

private Observable<List<String>> query1() { 
    List<String> urls = new ArrayList<>(); 
    urls.add("1"); 
    urls.add("2"); 
    urls.add("3"); 
    urls.add("4"); 

    return Observable.just(urls); 
} 

private Observable<List<String>> query2() { 
    List<String> urls = new ArrayList<>(); 
    urls.add("A"); 
    urls.add("B"); 
    urls.add("C"); 
    urls.add("D"); 

    return Observable.just(urls); 
} 

, а затем попытался объединить два списка:

Observable.zip(
      query1(), 
      query2(), 
      new Func2<List<String>, List<String>, Observable<String>>() { 
       @Override 
       public Observable<String> call(List<String> a1, List<String> a2) { 
        List<String> list = new ArrayList<>(); 
        list.addAll(a1); 
        list.addAll(a2); 
        return Observable.from(list); 
       } 
      }) 
      .subscribe(new Action1<String>() { // <-- It says, cannot resolve method subscribe 
       @Override 
       public void call(String string) { 
        String text = testTextView.getText().toString(); 
        testTextView.setText(text + "\n" + string); 
       } 
      }); 

Что я делаю неправильно? Я ожидал получить на мой взгляд B C D

EDIT1 Я закончил со следующим ответом:

Observable.zip(
      query1(), 
      query2(), 
      new Func2<List<String>, List<String>, List<String>>() { 
       @Override 
       public List<String> call(List<String> a1, List<String> a2) { 
        List<String> list = new ArrayList<>(); 
        list.addAll(a1); 
        list.addAll(a2); 
        return list; 
       } 
      }) 
      .flatMap(new Func1<List<String>, Observable<String>>() { 
       @Override 
       public Observable<String> call(List<String> urls) { 
        return Observable.from(urls); 
       } 
      }) 
      .subscribe(new Action1<String>() { 
       @Override 
       public void call(String string) { 
        String text = testTextView.getText().toString(); 
        testTextView.setText(text + "\n" + string); 
       } 
      }); 

EDIT2concat раствора как было предложено ihuk, было бы намного лучше в этом случае. Цените все ответы.

ответ

17

Я считаю, что операторы вы ищете являются concat или merge.

Concat будет излучать выбросы от двух или более Observable s без чередование их.

Merge, с другой стороны, объединяет несколько наблюдаемых путем слияния их выбросов.

Например:

String[] numbers = {"1", "2", "3", "4"}; 

    String[] letters = {"a", "b", "c", "d"}; 

    Observable<String> query1 = Observable.from(numbers).delay(1, TimeUnit.SECONDS); 
    Observable<String> query2 = Observable.from(letters); 

    Observable 
      .concat(query1, query2) 
      .subscribe(s -> { 
       System.out.printf("-%s-" + s); 
      }); 

Напечатает -1--2--3--4--a--b--c--d-. Если вы замените concat на merge, результат будет -a--b--c--d--1--2--3--4-.

Zip Оператор будет комбинировать несколько Observable с вместе с помощью указанной функции. Например,

Observable 
      .zip(query1, query2, (String n, String l) -> String.format("(%s, %s)", n, l)) 
      .subscribe(s -> { 
       System.out.printf("-%s-", s); 
      }); 

Вывод -(1, a)--(2, b)--(3, c)--(4, d)-.

+0

Спасибо за пример 'concat'. – krisk

1

то потому что вы пытаетесь вернуть Наблюдаемые из функции почтового индекса, а затем вы передаете Action<String>

Observable.zip(
      query1(), 
      query2(), 
      new Func2<List<String>, List<String>, List<String>>() { 
       @Override 
       public List<String> call(List<String> a1, List<String> a2) { 
        List<String> list = new ArrayList<>(); 
        list.addAll(a1); 
        list.addAll(a2); 
        return list; 
       } 
      }) 
      .subscribe(
        (string)-> System.out.println(string) 
      ); 
+0

Мне пришлось добавить flatMap к этому, что вы разместили (отредактировал мой вопрос). – krisk

0
Observable<List<String>> query1(){ 
     List<String> s = new ArrayList<>(); 
     s.add("1");s.add("1");s.add("1"); 
     return Observable.just(s); 
    } 
    Observable<List<String>> query2(){ 
     List<String> s = new ArrayList<>(); 
     s.add("1");s.add("1");s.add("1"); 
     return Observable.just(s); 
    } 
    void HelloRx(){ 
     Map<String,String> map2=new LinkedHashMap<>();//pick the result you want to return Here ! 
     Observable.zip(query1(),//Observable Method 1 
       query2(),//Observable Method 2 
       (result1,result2)->{ 
        for(String s : result1){//result1 is the value returned by query1 , result2 ...u know. 
         //do whatever you want 
         //map.put(......) 
        } 
        return null; 
       }) 
       .subscribeOn(BackgroundSchedulers.getMultiThreadInstance()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .doOnCompleted(() -> { 
        //Do Something when finish for example transmit data to your adapter 
       }) 
       .subscribe(); 
    } 
0

По-видимому, чтобы объединить два списка в один список, вы можете сделать Observable.concat() на их Observable.from() с, а затем вызвать Observable.toList().

RealmResults<Cat> equalTo; 
RealmResults<Cat> beginsWith; 

@Override 
public void onViewRestored() { 
    compositeSubscription = new CompositeSubscription(); 
    equalTo = realm.where(Cat.class).equalTo("field", filterString).findAllSorted("field"); 
    beginsWith = realm.where(Cat.class).beginsWith("field", filterString).findAllSorted("field"); 
    compositeSubscription.add(realm.asObservable() 
      .switchMap(new Func1<Realm, Observable<Cat>>() { 
       @Override 
       public Observable<Cat> call(Realm realm) { 
        return Observable.concat(Observable.from(equalTo), Observable.from(beginsWith)); 
       } 
      }) 
      .toList() 
      .subscribe(cats -> { 
       // update adapter with List<Cat> 
      }));