2017-09-06 28 views
3

我對Rx編程非常陌生,我在項目中嘗試瞭解它。我要的是我有如下GamesInfoList的對象:RxJava2:在Observable中過濾列表<Object>

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

在這裏,我過濾(使用濾波器()算子)的對象的平臺根據此方法所輸入的名稱。上面的方法顯示我錯誤,因爲平臺類型爲List。如何通過列表篩選匹配名稱並顯示在我的Android應用程序中?爲了按日期和名稱加載數據,需要對上述方法進行哪些更改?

回答

3

最簡單的方法是迭代第二個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)); 
} 
+0

我想這應該工作得很好,因此,我會接受這個答案。將測試一次。非常感謝!!! :-) –

+1

有時最簡單的解決方案是最好的。也許你可以建立更多的RXy和聰明的東西,但最終它會更難以理解下一個讀取它的人。或者一個月後給你;) – theFunkyEngineer

+0

是的,我想是的。操作員很難記住。需要在我所預計的很多項目中使用它們。 –

-1

那麼您需要覆蓋GamePlatformInfo類中的equals()方法。

我假設你有GamePlatformInfo類下面的類定義:

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

然後你只需要使用運營商通過列表來搜索。 檢查以下修改的摘錄:

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()方法則list.contains()方法使用給定等於定義對比清單的項目類的列表。

我希望它有幫助。

+0

這是不正確的。 'List#contains'工作使用類的equals方法,而不是'compareTo',如文檔[here](https://docs.oracle.com/javase/7/docs/api/java/util/List.html #contains(java.lang.Object中))。爲了這個用例而重寫你的類的'equals'是一個非常糟糕的主意,因爲它可能會在其他地方引起問題。 – theFunkyEngineer

+0

@theFunkyEngineer你是對的。 「Comparable」用於排序我已更正答案。凌駕平等並不是一個壞主意。如果你正確實施它不會破壞任何東西。看一下'equals()'的實現。即使它使用列表時最好的做法,而不是盲目迭代使用for循環的列表。 – chandil03

+0

@theFunkyEngineer在RxJava中,最好的做法是打破您在列表中搜索過的'Observable'鏈。我並不是說你錯了,但這就是應該如何編寫慣用代碼。沒有冒犯,謝謝理解。 – chandil03