2015-03-03 16 views
6

Cercando di capire tutto ciò che è roba RxJava. Stavo facendo seguente esempio:Android RxJava che unisce le liste

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); 
} 

e poi ha cercato di unire due liste:

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); 
       } 
      }); 

quello che sto facendo di sbagliato? Mi aspettavo di ottenere, a mio avviso A B C D

EDIT1 ho finito con la seguente risposta:

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 soluzione come suggerito da ihuk sarebbe molto meglio in questo caso. Apprezzo per tutte le risposte.

risposta

17

Credo che i gestori si sta cercando sono concat o merge.

Concat emetterà le emissioni da due o più Observable s senza interfogliandoli.

Merge d'altro canto combinerà più osservabili unendo le loro emissioni.

Ad esempio:

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); 
      }); 

Stamperà -1--2--3--4--a--b--c--d-. Se sostituisci concat con merge il risultato sarà -a--b--c--d--1--2--3--4-.

Zip l'operatore combinerà più Observable s insieme tramite la funzione specificata. Per esempio

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

Will uscita -(1, a)--(2, b)--(3, c)--(4, d)-.

+0

Grazie per l'esempio 'concat'. – krisk

1

thats perché si sta tentando di tornare osservabile dalla funzione di cerniera, ma poi si passa 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

Ho dovuto aggiungere flatMap a ciò che hai postato (modificato la mia domanda). – 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

A quanto pare per unire due liste in una lista, si può fare Observable.concat() sulle loro Observable.from() s e quindi chiamare 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> 
      }));