2017-02-13 3 views
2

J'essaye de filtrer une liste avec RxJava2 de sorte que chaque article (objet) dans la liste doive passer un contrôle de validation et j'obtiens une liste résultante avec seulement des articles qui passent ce test. Par exemple, si mon objet avait la structure suivante,RxJava2 filter Liste <Object>

class MyClassA { 
    int value1; 
    int value2; 
} 

Je veux seulement obtenir la liste des articles où le value2 est 10.

J'ai une fonction d'appel d'API qui retourne un Observable de la liste, à savoir Observable<List<MyClassA>> comme suit,

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

et je voudrais avoir la sortie filtrée, donc j'essayé d'ajouter un opérateur .filter() à ce qui précède, mais il semble exiger un Predicate<List<MyClassA>> au lieu d'un MyClassA objet avec lequel je peux vérifier et autoriser seulement ceux où value2 == 10.

Je suis assez nouveau pour RxJava et RxJava2 et il me semble qu'il me manque quelque chose de basique ici?

TIA

Répondre

14

Vous pouvez déroulez la liste et collecter les entrées qui en ont passé le filtre:

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

pourriez-vous s'il vous plaît étendre le lambda au code pré Java 8? aiderait vraiment à voir de cette façon – Bootstrapper

+0

Ne fonctionne pas avec fluide –

0

Vous pourriez jeter un oeil au-dessous. Il montre les moyens d'imprimer uniquement les objets filtrés OU les listes contenant des objets filtrés. Ici la logique de filtrage est de conserver les org.apache.commons.lang3.tuple.Pair s qui ont des nombres pairs dans le droit.

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

} 

sortie avec le contenu d'observable:

[(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)] 

sortie à contenir des objets uniquement filtrés:

(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) 

sortie pour contenir les listes qui contiennent des objets uniquement filtrés.

[(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)]