Фильтровать элементы списка при слиянии двух списков RxJava - PullRequest
1 голос
/ 11 марта 2019

Я объединяю два списка объекта Item, и мне нужно, чтобы в списке не было повторяющихся элементов, но я не знаю, как два фильтруют дублирующиеся элементы.Вот фрагмент кода:

class Item {
    int id;
    String name;
}

//How to filter duplicate items of the list with rx???
private Observable<List<Item>> getItems() {
    return Observable.merge(getListFromSourceOne(), getListFromSourceTwo());
}

private Observable<List<Item>> getListFromSourceOne() {
    Item item1 = new Item(1, "arnold");
    Item item2 = new Item(2, "jerry");

    List<Item> list = new ArrayList();
    list.add(item1);
    list.add(item2);

    return Observable.just(list);
}

private Observable<List<Item>> getListFromSourceTwo() {
    Item item1 = new Item(1, "arnold");
    Item item2 = new Item(3, "angelica");

    List<Item> list = new ArrayList();
    list.add(item1);
    list.add(item2);

    return Observable.just(list);
}

1 Ответ

1 голос
/ 12 марта 2019

Здесь много вариантов.Я просто перечисляю некоторые из них, которые можно запомнить.Давайте предположим, что ваша модель предмета правильно реализует метод equals.

  1. Использование отдельный

Просто сопоставьте наблюдаемое с чем-то, что испускает элементы один за другим.

Observable.merge(getListFromSourceOne(),
               getListFromSourceTwo())
  .flatMap(list -> Observable.fromIterable(list))
  .toList();
Использование map

По сути, преобразовать список в набор, который удаляет дубликаты, а затем обратно в список.Честно говоря, довольно много ненужных операций.

Observable.merge(getListFromSourceOne(),
                  getListFromSourceTwo())
  .map(list -> new HashSet(list))
  .map(set -> new ArrayList(set));
Использование zip

Даже не использовать слияние:

 getListFromSourceOne()
  .zipWith(getListFromSourceTwo(), (list1, list2) -> {
      List<Item> result = new ArrayList(list1);

      for(Item I : list2)
         if(!result.contains(I))
            result.add(I);
    });

Опять не самая эффективная вещь в мире.

Что-то еще

Полагаю, лучший вариант - использовать distinct и, возможно, подключить его еще до того, как вы включите списки:

private Observable<List<Item>> getItems() {
  return Observable.merge(getListFromSourceOne(), getListFromSourceTwo())
                .distinct()
                .to list();
}

private Observable<Item> getListFromSourceOne() {
  Item item1 = new Item(1, "arnold");
  Item item2 = new Item(2, "jerry");

  return Observable.just(item2, item2);
}

private Observable<List<Item>> getListFromSourceTwo() {
  Item item1 = new Item(1, "arnold");
  Item item2 = new Item(3, "angelica");

  return Observable.just(item2, item2);
}
...