使用 RxJava 来解析一个项目并从之前的项目中创建一个新项目

Use RxJava in order to parse an item and create a new one from the previous

我有以下对象,我想使用 RxJava 来创建一个新对象。这背后的逻辑是每篇文章都有很多评论。它使用 ArticleData.commentId 和 Comment.id 找到正确的注释。

public class ArticlesResponse  {
    public List<ArticleData> articles;
    public List<Data> comments;
}

public class Data {
    public int id;
    public String link;
    public String title;
    public String author
    public String body;
}

public class ArticleData extends Data {
        public List<int> commentId;
}

那么我如何使用 Rxjava 来创建以下对象

public class Article extends Data {
        public List<Comments> comments;
}

public class Comments extends Data {
      // comments will have more attributes in the feature
      // so use a seperate object
}

我知道我必须使用 flapMap 和过滤器来解析 "ArticleResponse" 但我不知道如何将所有这些放在一起。 此外,"ArticleResponse" 是从我从 Retrofit 获得的 json 生成的,所以我想使用 RxJava 会更好,因为我已经有了 Observable 而不是将嵌套的 for 放在我的回调中。

对您的实际问题有点困惑,希望这对您有所帮助。 Retrofit 可以 return 一个 Observable 给你,这应该使 RxJava 集成变得容易。例如,在您的服务中,您可以:

@GET(<your endpoint>)
Observable<ArticlesResponse> getArticles();

并这样称呼它:

<yourService>.getArticles()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedules.mainThread())
    .subscribe() // manipulate how you want

我假设你的意思是 articlesResponse.comments 是一个包含所有 ArticleData 的所有 Comments 的列表,虽然我不认为将这些数据包装在一起并在客户端进行地图操作是个好主意,这个工作应该在服务器上完成。

而且我想也许您的 ArticlesResponsecomments 字段应该是 List<Comments>

有了这些假设,下面的代码可能会完成你想要的工作(我把它们放在 TempTest class 中,并定义一个你描述的接口,并模拟它以通过 javac 编译,为了简化代码,我还使用 Java 8 lambda 语法)。

public class TempTest {

  public static class Data {
    public int id;
    public String link;
    public String title;
    public String author;
    public String body;
  }

  public static class ArticleData extends Data {
    public List<Integer> commentId;
  }

  public static class Comments extends Data {
    // comments will have more attributes in the feature
    // so use a seperate object
  }

  public static class ArticlesResponse {
    public List<ArticleData> articles;
    public List<Comments> comments;
  }

  public class Article extends Data {
    public List<Comments> comments;
  }

  public interface TestInterface {
    Observable<ArticlesResponse> getArticle();
  }

  public static Comments findCommentWithId(int commentId, List<Comments> comments) {
    for (Comments comment : comments) {
        if (comment.id == commentId) {
            return comment;
        }
    }
    return null;
  }

  @Test
  public void simpleTestcase() {
    // assume you means that articlesResponse.comments is a list contains all Comments of these
    // all ArticleData, although I don't think wrap these data together and do the map operation
    // in client is a good idea, this job should be done at server
    TestInterface testInterface = mock(TestInterface.class);
    testInterface.getArticle().map(articlesResponse -> {
        List<Article> result = new ArrayList<>();
        // for each ArticleData in articlesResponse.articles
        for (ArticleData articleData : articlesResponse.articles) {
            // get all Comments from articlesResponse.comments
            Article article = new Article();
            // ... copy Data field from articleData to article
            article.comments = new ArrayList<>();
            for (Integer id : articleData.commentId) {
                Comments comment = findCommentWithId(id, articlesResponse.comments);
                if (comment != null) {
                    article.comments.add(comment);
                }
            }
            result.add(article);
        }
        return result;
    }).subscribe(articles -> {
        for (Article article : articles) {
            System.out.println(article);
        }
    });
  }
}