RxJava2。从列表

时间:2017-11-23 22:08:42

标签: rx-java rx-java2

假设

  1. 有一个用户类,其中包含两个属性名称年龄
  2. 我们获得了一个用户列表
  3. 我们需要处理每个用户的两个属性。
  4. 是否可以处理每个用户的两个属性?

    以下代码不正确,我知道。但如何使其正确?也许有任何运营商可以让它发挥作用?

    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))
    

3 个答案:

答案 0 :(得分:1)

您可以将这两个属性作为单曲处理并将结果压缩在一起并使用flatMapSingle将其平面映射。在doOnNext中,每个zip都有一个Container。

@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 + '}';
    }
  }

答案 1 :(得分:0)

我不确定你想做什么,但从我认为你有一个users列表中可以观察到的问题,你需要处理nameage每个用户,最后使用更新的user数据。为此,您不能使用单个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
            });

答案 2 :(得分:0)

我最终得到了一个容器解决方案

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