Rx java RxJava2。处理列表中对象的不同属性
假定Rx java RxJava2。处理列表中对象的不同属性,rx-java,rx-java2,Rx Java,Rx Java2,假定 有一个类User,具有两个属性name和age 我们得到一个用户列表 我们需要处理每个用户的两个属性 是否可以同时处理每个用户的两个属性 我知道下面的代码不正确。但是如何使它正确呢?也许有操作员让它工作 Observable.fromIterable(users) .map(user -> user.name) .map(string -> new NameVM(string)) .map(user -> user.age) .map(in
Observable.fromIterable(users)
.map(user -> user.name)
.map(string -> new NameVM(string))
.map(user -> user.age)
.map(int -> new AgeVM(int))
我只有一个想法,但我不太喜欢
Observable.fromIterable(users)
.doOnNext(user -> new NameVM(string))
.map(user -> user.age)
.map(int -> new AgeVM(int))
我不知道你想做什么,但从这个问题上看,我认为你有一个可观察的
用户列表
,你需要处理每个用户的姓名
和年龄
,最后使用更新的用户
数据。为此,为什么不能使用单个map
操作符
Observable.fromIterable(users)
.map(user -> {
user.name =//do something with name);
user.age = // do something with age);
return user;
}).subscribe(user -> {
// here you get the result with processed user object
});
您可以将这两个属性都作为单个属性处理,然后将结果压缩在一起,并使用flatMapSingle进行flatMap。在doOnNext中,每个拉链都有一个容器
@Test
void name2() throws Exception {
List<User> users =
Arrays.asList(
new User("hans", 30), new User("leon", 66), new User("Uwe", 45), new User("Michi", 23));
Observable<Container> containerObservable =
Observable.fromIterable(users)
.flatMapSingle(
user -> {
Single<ProcessedAge> processedAgeSingle = processeAge(user.age);
Single<ProcessedUserName> processedUserNameSingle =
processeUserName(user.userName);
return Single.zip(
processedAgeSingle,
processedUserNameSingle,
(age, name) -> {
return new Container(age, name);
});
})
.doOnNext(System.out::println);
containerObservable.test().await().assertValueCount(4);
}
private Single<ProcessedAge> processeAge(int age) {
return Single.just(new ProcessedAge());
}
private Single<ProcessedUserName> processeUserName(String userName) {
return Single.just(new ProcessedUserName());
}
class User {
String userName;
int age;
public User(String userName, int age) {
this.userName = userName;
this.age = age;
}
}
class ProcessedUserName {}
class ProcessedAge {}
class Container {
ProcessedUserName userNameResult;
ProcessedAge ageResult;
public Container(ProcessedAge age, ProcessedUserName name) {
this.userNameResult = name;
this.ageResult = age;
}
@Override
public String toString() {
return "Container{" + "userNameResult=" + userNameResult + ", ageResult=" + ageResult + '}';
}
}
@测试
void name2()引发异常{
列出用户=
Arrays.asList(
新用户(“hans”,30),新用户(“leon”,66),新用户(“Uwe”,45),新用户(“Michi”,23));
可观测的容器可观测的=
可观察的。从可观察的(用户)
.flatMapSingle(
用户->{
单个ProcessedAgesSingle=processeAge(user.age);
单进程服务器名称单=
processeUserName(user.userName);
返回Single.zip(
加工单体,
processedUserNameSingle,
(年龄、姓名)->{
返回新容器(年龄、名称);
});
})
.doOnNext(System.out::println);
containerObservable.test().await().assertValueCount(4);
}
专用单进程(int age){
返回Single.just(newprocessedage());
}
私有单进程userName(字符串用户名){
返回Single.just(newprocessedUserName());
}
类用户{
字符串用户名;
智力年龄;
公共用户(字符串用户名,整数){
this.userName=用户名;
这个。年龄=年龄;
}
}
类ProcessedUserName{}
类ProcessedAge{}
类容器{
ProcessedUserName用户名结果;
经处理的ageResult;
公共容器(ProcessedAge年龄、ProcessedUserName名称){
this.usernamesult=name;
this.ageResult=年龄;
}
@凌驾
公共字符串toString(){
返回“Container{“+”usernamesult=“+usernamesult+”,ageResult=“+ageResult+'}”;
}
}
我最终得到了一个容器解决方案
class ContainerVM {
public NameVM nameVM;
public AgeVM ageVM;
}
Observable.fromIterable(users)
.map(user -> buildContainerVM(user));
private ContainerVM buildContainerVM(User user) {
ContainerVM containerVM = new ContainerVM();
containerVM.nameVM = new NameVM(user.name);
containerVM.ageVM = new AgeVM(user.age);
}
名称和年龄的处理是否应该在同一类型async上完成?name/age process->returntype的结果是什么?刚刚通过返回someVM修改了我的问题。处理这两个结果,然后返回一个包含这两个结果的新容器是否足够?在下一个操作符中,您将得到NameVM和AgetVM?的结果,实际上最终得到的是容器解决方案,但比您的回答中的结果要简单一点。完全不建议在一个管道步骤中修改对象。你应该创建一个新的,并传递下来,或使用doOnNext的副作用。但是请记住,通过管道步骤传递的对象应该是不可变的。我不想修改用户对象,而是创建一个将对象与名称和年龄分开的对象。看到我的修改了吗