2017-11-19 14 views
0

나는 의심의 여지를 나타 내기 위해 내가 만든 클래스를 아래에 가지고있다.groupBy 작업을 실행 한 후 여러 객체를 단일 객체로 병합하는 방법은 무엇입니까?

내 유동성에 초기 변환을 수행 한 후 내가 가진 :

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가 사용자 정보를 포함하는 각 그룹에 대해 하나 개의 객체를 방출 유동성에 동일한 ID, 개체 및 점수의 합계.

그래서 결과는 방출이 유동성 될 것입니다 :

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

내가 (내가 HashMaps을 함께 뭔가를하고 동일한 결과를 얻을 수 알고) 가능하면 RxJava이 작업을 수행하고자합니다.

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 연산자를 적용하여 사용자 객체를 만듭니다.

그것은 데이터를 보유하고 초기 공급 업체로서 새로운 사용자 개체 (User::new)을 생성 :

+0

ID별로 그룹화 된 UserScoreTO를 인쇄합니다. 이러한 객체를 User 객체로 변형하여 반복되는 UserScoreTO를 User 객체로 병합하고 점수를 추가하려고합니다. 예상 결과는 질문의 본문에 표시됩니다. – alexpfx

1

몇 가지 조사를하고 시행 착오 코드를 많이 수행 한 후, 나는 속임수를 썼는지이 [collect][1] 연산자를 발견 그룹의 모든 항목에서 그래서 속성을 설정하고 점수를 증가시켜 그룹 반복이 끝나면 점수를 반환합니다.

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} 
내가 코드를 단순화 할 수 있다면 나는 이것이 가장 좋은 방법 있는지 알고하지 않거나 RxJava에 새로운 해요,하지만 결과 코드이기 때문에