2015-03-03 15 views
6

Próbuje zrozumieć wszystkie te rzeczy RxJava. Robiłem następujący przykład:Android RxJava łączy listę

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

a następnie próbował przyłączyć dwóch list:

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

Co robię źle? Spodziewałem się dostać moim zdaniem B C D

Edit1 skończyło z następującą odpowiedź:

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 rozwiązanie jak sugeruje to Huk, byłoby znacznie lepiej w tym przypadku. Doceniam wszystkie odpowiedzi.

Odpowiedz

17

wierzę operatorzy szukasz są concat lub merge.

Concat będzie emitować emisje z dwóch lub większej liczby Observable s bez przeplatania ich w trybie.

Merge z drugiej strony połączy wiele obserwowanych obiektów poprzez połączenie ich emisji.

Na przykład:

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

wypisze -1--2--3--4--a--b--c--d-. Jeśli zastąpisz concat wartością merge, wynik będzie wynosił .

Zip Operator połączy wiele różnych Observable s razem za pomocą określonej funkcji. Na przykład:

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

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

+0

Dzięki za przykład "concat". – krisk

1

ów, ponieważ starają się powrócić Obserwowalne z funkcji zip, ale potem można przekazać 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

Musiałem dodać flatMap do tego, co napisałeś (zredagowałem moje pytanie). – 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

Widocznie dołączyć dwie listy do jednej listy, można zrobić Observable.concat() na ich Observable.from() s, a następnie zadzwonić 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> 
      }));