2017-02-13 3 views
2

Ich versuche, eine Liste mit RxJava2 so zu filtern, dass jedes Element (Objekt) in der Liste eine Validierungsprüfung bestehen sollte und ich eine Ergebnisliste mit nur Elementen erhalte, die diesen Test bestehen. Zum Beispiel, wenn mein Objekt hatte die folgende Struktur,RxJava2 filter Liste <Object>

class MyClassA { 
    int value1; 
    int value2; 
} 

ich nur wollen, um die Liste der Elemente, wo die value2 10.

ist ich einen API-Aufruf Funktion, die eine beobachtbare der Liste zurückgibt, dh Observable<List<MyClassA>> wie

apiService.getListObservable() 
    .subscribeOn(Schedulers.io) 
    .observeOn(AndroidSchedulers.mainThread()); 

und ich möchte haben die Ausgabe gefiltert, so habe ich versucht, das Hinzufügen eines .filter() Bediener auf die oben folgt, aber es scheint eine Predicate<List<MyClassA>> statt nur einzu verlangenObjekt, mit dem ich nur überprüfen und zulassen kann, wo value2 == 10.

Ich bin ziemlich neu bei RxJava und RxJava2 und es scheint, als würde ich hier etwas Grundlegendes vermissen?

TIA

Antwort

14

Sie die Liste abrollen und dann die Einträge aufsammeln, die den Filter passiert:

apiService.getListObservable() 
.subscribeOn(Schedulers.io) 
.flatMapIterable(new Function<List<MyClassA>, List<MyClassA>>() { 
    @Override public List<MyClassA> apply(List<MyClassA> v) { 
     return v; 
    } 
}) 
.filter(new Predicate<MyClassA>() { 
    @Override public boolean test(MyClassA v) { 
     return v.value2 == 10; 
    } 
}) 
.toList() 
.observeOn(AndroidSchedulers.mainThread()) 
.subscribe(...); 
+0

Könnten Sie bitte die Lambda's vor Java 8 Code erweitern? würde wirklich helfen, es so zu sehen – Bootstrapper

+0

Funktioniert nicht mit Flowable –

0

Sie können auf der unten einen Blick darauf werfen. Es zeigt die Möglichkeiten, nur die gefilterten Objekte ODER die Listen zu drucken, die gefilterte Objekte enthalten. Hier soll die Filterlogik die org.apache.commons.lang3.tuple.Pair s behalten, die gerade Zahlen rechts haben.

public static void main(String[] args) { 
    // print raw output 
    getListObservable().subscribe(System.out::println); 

    // print the objects post filtering 
    getListObservable().flatMap(v -> Observable.from(v)).filter(p -> p.getRight()%2==0).subscribe(System.out::println); 

    // print the list refined with only filtered objects 
    getListObservable().flatMap(v -> Observable.just(v.stream().filter(p -> p.getRight()%2==0).collect(Collectors.toList()))).subscribe(System.out::println); 

} 

private static Observable<List<Pair<Integer, Integer>>> getListObservable() { 
    return Observable.create(subscriber -> { 
     for(int i=0; i<5; i++){ 
      List<Pair<Integer, Integer>> list = new ArrayList<>(); 
      for(int j=0; j<5; j++){ 
       list.add(Pair.of(i, j)); 
      } 
      subscriber.onNext(list); 
     } 
    }); 

} 

Ausgabe mit Inhalt beobachtbar:

[(0,0), (0,1), (0,2), (0,3), (0,4)] 
[(1,0), (1,1), (1,2), (1,3), (1,4)] 
[(2,0), (2,1), (2,2), (2,3), (2,4)] 
[(3,0), (3,1), (3,2), (3,3), (3,4)] 
[(4,0), (4,1), (4,2), (4,3), (4,4)] 

Output nur gefilterte Objekte enthalten:

(0,0) 
(0,2) 
(0,4) 
(1,0) 
(1,2) 
(1,4) 
(2,0) 
(2,2) 
(2,4) 
(3,0) 
(3,2) 
(3,4) 
(4,0) 
(4,2) 
(4,4) 

Ausgabe der Listen enthalten, die nur gefilterte Objekte enthalten.

[(0,0), (0,2), (0,4)] 
[(1,0), (1,2), (1,4)] 
[(2,0), (2,2), (2,4)] 
[(3,0), (3,2), (3,4)] 
[(4,0), (4,2), (4,4)]