RxJava2:过滤 Observable 中的列表 <Object>

RxJava2 : Filtering a List<Object> in an Observable

我是 Rx 编程的新手,我正在一个项目中尝试使用它。我想要的是我有一个 GamesInfoList 对象,如下所示:

@AutoValue
public abstract class GameInfoList {
    public static TypeAdapter<GameInfoList> typeAdapter(Gson gson) {
        return new AutoValue_GameInfoList.GsonTypeAdapter(gson);
    }

    public static Builder builder() {
        return new AutoValue_GameInfoList.Builder();
    }

    public abstract long id();

    @Nullable
    public abstract String date_added();

    @Nullable
    public abstract String date_last_updated();

    @Nullable
    public abstract GameImages image();

    @Nullable
    public abstract String name();

    @Nullable
    public abstract List<GamePlatformInfo> platforms();

    @AutoValue.Builder
    public abstract static class Builder {

        public abstract Builder id(long id);

        public abstract Builder date_added(String date_added);

        public abstract Builder date_last_updated(String date_last_updated);

        public abstract Builder image(GameImages image);

        public abstract Builder name(String name);

        public abstract Builder platforms(List<GamePlatformInfo> platforms);

        public abstract GameInfoList build();
    }
}

现在,我想按日期和名称加载我的游戏,我为此编写了一个方法来访问其中的上述对象。

public void loadGamesByDateAndName(String date, String name) {
    Timber.d("Load games by date: " + date + " and name: " + name);
    remoteDataHelper
            .getGamesListByDate(date)
            .flatMapObservable(Observable::fromIterable)
            .filter(game -> game.platforms() != null)
            .filter(game -> game.platforms().name().contains(name))
            .toList()
            .subscribe(getObserverFiltered(name, false));
}

在这里,我根据在此方法中输入的名称过滤(使用 filter() 运算符)平台对象。上面的方法向我显示错误,因为平台是 List 类型。如何筛选列表以匹配名称并显示在我的 Android 应用程序中?为了按日期和名称加载数据,需要对上述方法进行哪些更改?

最简单的方法是在第二个 filter 运算符中迭代。

public void loadGamesByDateAndName(String date, String name) {
    Timber.d("Load games by date: " + date + " and name: " + name);
    remoteDataHelper
            .getGamesListByDate(date)
            .flatMapObservable(Observable::fromIterable)
            .filter(game -> game.platforms() != null)
            .filter(game -> { for(GamePlatformInfo platform : game.platforms()){
                                  if(platform.name().contains(name)) {
                                      return true;
                                  }
                              }
                              return false;
                    }
            )
            .toList()
            .subscribe(getObserverFiltered(name, false));
}

好吧,您需要重写 GamePlatformInfo class 中的 equals() 方法。

我假设您有以下 class 对 GamePlatformInfo class 的定义:

class GamePlatformInfo{
    String name;
    ...
    ...

    public GamePlatformInfo(String name){
        this.name = name;
        ...
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof GamePlatformInfo)) return false;
        final GamePlatformInfo other = (GamePlatformInfo)o;
        return name.equals(other.name);
    }

    @Override
    public int hashCode() {
        int result = 17;
        result = 31 * result + name.hashCode();
        return result;
    }
}

然后您只需要使用 contains() 运算符来搜索该列表。 检查以下修改后的代码段:

public void loadGamesByDateAndName(String date, String name) {
    Timber.d("Load games by date: " + date + " and name: " + name);
    remoteDataHelper 
            .getGamesListByDate(date) 
            .flatMapObservable(Observable::fromIterable) 
            .filter(game -> game.platforms() != null) 
            .filter(game -> game.platforms().contains(new GamePlatformInfo(name))) // This is all you need to do to search through the list.
            .toList() 
            .subscribe(getObserverFiltered(name, false));
} 

在幕后:如果您创建一个覆盖 equals() 方法的 class 列表,那么 list.contains() 方法使用给定的 equals 定义来比较列表项。

希望对您有所帮助。