执行groupBy操作后如何将多个对象合并为一个? [英] How to merge several objects into a single one after execute the groupBy operation?
问题描述
我创建了下面的类来说明我的疑问.
I have the class below that I've created to illustrate my doubt.
在对 Flowable 进行初始转换后,我有:
After doing the initial transformations on my flowable I have:
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}
我想将具有相同 id 的 UserScoreTO 对象组合到一个 Flowable 中,该 Flowable 为每个组发出一个对象,其中包含用户信息和分数总和.
I want to combine UserScoreTO objects with the same id into a Flowable that emits one single object for each group, that contains the user information and the sum of the scores.
所以结果将是可流动的:
So the result will be flowable that emits:
User (1, "john", 10);
User (2, "paul", 6);
User (3, "mark", 8);
如果可能的话,我想用 RxJava 来做这件事(我知道我可以用 HashMap 做一些事情来达到同样的结果).
I want to do this with RxJava if possible (I know I could achieve same result doing something with HashMaps).
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 +
'}';
}
}
}
推荐答案
您提供的代码已经完全符合您的要求.groupBy 会将具有相同 id 的 UserScoreTO 对象分组到同一个 GroupedFlowable 对象中.
The code you provided already does exactly what you want. groupBy will group UserScoreTO objects with the same id into the same GroupedFlowable object.
好的,我明白了,也许以下可以更好地满足您的需求
Okay I see, maybe the following does what you want a little bit better
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));
}
您想要的是通过应用 reduce 运算符将 UserScoreTo 聚合到同一个 User 对象中.
What you want is to aggregate the UserScoreTo into the same User object by applying the reduce operator.
这篇关于执行groupBy操作后如何将多个对象合并为一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!