在合并两个列表 RxJava 时过滤列表项

Filter List items on merge of two lists RxJava

我正在合并两个 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);
}

这里有很多选项。我只是列出一些想到的。假设您的项目模型正确实施了 equals 方法。

  1. 使用distinct

简单地将 observable 映射到一个一个发射项目的东西。

Observable.merge(getListFromSourceOne(),
               getListFromSourceTwo())
  .distinct()
  .flatMap(list -> Observable.fromIterable(list))
  .toList();
  1. 使用map

基本上将列表转换为一个集合,删除重复项然后返回列表。老实说,很多不必要的操作。

Observable.merge(getListFromSourceOne(),
                  getListFromSourceTwo())
  .map(list -> new HashSet(list))
  .map(set -> new ArrayList(set));
  1. 使用zip

甚至不要使用合并:

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

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

这又不是世界上最高效的事情。

  1. 其他

我想最好的选择是使用 distinct 并且可能甚至在您转换列表之前就将其插入:

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

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