2017-11-19 8 views
0

私は疑問を説明するために私が作成した下のクラスを持っています。groupBy操作を実行した後、複数のオブジェクトを1つにマージする方法はありますか?

私の流動性の上で最初の変換を行った後、私は持っている:

UserScoreTO{id=1, name='john', score=4} 
UserScoreTO{id=1, name='john', score=5} 
UserScoreTO{id=1, name='john', score=1} 
UserScoreTO{id=2, name='paul', score=4} 
UserScoreTO{id=2, name='paul', score=2} 
UserScoreTO{id=3, name='mark', score=1} 
UserScoreTO{id=3, name='mark', score=7} 

は私が組み合わせたいUserScoreTOは、ユーザー情報が含まれているグループごとに1つのオブジェクトを発するフロアブルに同じIDとオブジェクトとスコアの合計

だから、結果が発する流動可能になります:私は、可能な場合RxJavaでこれをやりたい

User (1, "john", 10); 
User (2, "paul", 6); 
User (3, "mark", 8); 

(私はハッシュマップで何かをやって同じ結果を得ることができ知っているが)。

package examples.rxjava; 

import java.util.Arrays; 
import java.util.List; 

import io.reactivex.Flowable; 

import static java.lang.System.out; 

public class TestUsers { 

    public static void main(String[] args) { 
     new TestUsers().execute(); 
    } 


    public void execute() { 
     getUsers() 
       .flatMap(list -> Flowable.fromIterable(list)) 
       .groupBy(userScoreTO -> userScoreTO.id).subscribe(group -> group.subscribe(out::println)); 

    } 





    Flowable<List<UserScoreTO>> getUsers() { 
     return Flowable.fromCallable(
       () -> Arrays.asList(
         new UserScoreTO(1, "john", 4), 
         new UserScoreTO(1, "john", 5), 
         new UserScoreTO(1, "john", 1), 

         new UserScoreTO(2, "paul", 4), 
         new UserScoreTO(2, "paul", 2), 

         new UserScoreTO(3, "mark", 1), 
         new UserScoreTO(3, "mark", 7)) 
     ); 


    } 

    private class User { 
     private int id; 
     private String name; 
     private int totalScore; 

     public User(int id, String name, int totalScore) { 
      this.id = id; 
      this.name = name; 
      this.totalScore = totalScore; 
     } 

     @Override 
     public String toString() { 
      return "User{" + 
        "id=" + id + 
        ", name='" + name + '\'' + 
        ", totalScore=" + totalScore + 
        '}'; 
     } 
    } 

    private class UserScoreTO { 
     private int id; 
     private String name; 
     private int score; 


     public UserScoreTO(int id, String name, int score) { 
      this.id = id; 
      this.name = name; 
      this.score = score; 
     } 

     @Override 
     public String toString() { 
      return "UserScoreTO{" + 
        "id=" + id + 
        ", name='" + name + '\'' + 
        ", score=" + score + 
        '}'; 
     } 
    } 

} 

答えて

1

あなたが提供したコードは、あなたが望むものとまったく同じです。 groupByは、同じIDを持つUserScoreTOオブジェクトを同じGroupedFlowableオブジェクトにグループ化します。

編集:私は見

オーケー、多分次はあなたが欲しい何

public void execute() { 
getUsers() 
    .flatMap(Flowable::fromIterable) 
    .groupBy(userScoreTO -> userScoreTO.id) 
    .map(group -> group.reduce(new User(group.getKey(), "", 0), 
     (user, userScoreTO) -> { 
      user.name = userScoreTO.name; 
      user.totalScore += userScoreTO.score; 
      return user; 
     })) 
    .subscribe(userSingle -> userSingle.subscribe(System.out::println)); 

}

少し良く望むものを行うのと同じにUserScoreToを集約することですreduce演算子を適用してユーザーオブジェクトを作成します。

+0

IDでグループ化されたUserScoreTOを出力します。これらのオブジェクトをUserオブジェクトに変換し、繰り返したUserScoreTOをUserオブジェクトにマージしてスコアを追加します。期待される結果が質問の本文に表示されます。 – alexpfx

1

いくつかの研究を行うと、試行錯誤のコードの多くを行った後、私はトリックをしたこの[collect][1]オペレータが見つかりました:それはデータを保持している初期のサプライヤーとして、新たなユーザーオブジェクト(User::new)を作成

をグループのすべての項目からだから私はプロパティを設定し、スコアをインクリメントし、グループ反復の終わりにそれを返します。

私はRxJavaに新たなんだ、これが最善のアプローチである場合は、コードを簡略化することができる場合、私は知りませんが、結果のコードは次のとおりです。

getUsers() 
       .flatMap(list -> Flowable.fromIterable(list)) 
       .groupBy(userScoreTO -> userScoreTO.id) 
       .flatMap(groups -> Flowable.fromCallable(() -> groups.collect(User::new, (user, userscore) -> { 
        user.id = userscore.id; 
        user.name = userscore.name; 
        user.totalScore += userscore.score; 
       }))).subscribe(userSingle -> { 
      userSingle.subscribe(new SingleObserver<User>() { 
       @Override 
       public void onSubscribe(Disposable d) { 
        System.out.println("onSubscribe"); 
       } 

       @Override 
       public void onSuccess(User user) { 
        System.out.println(user); 
       } 

       @Override 
       public void onError(Throwable e) { 
        System.out.println(e); 

       } 
      }); 

     }); 

出力:

onSubscribe 
onSubscribe 
onSubscribe 
User{id=1, name='john', totalScore=10} 
User{id=2, name='paul', totalScore=6} 
User{id=3, name='mark', totalScore=8} 
関連する問題