我有以下对象,我想使用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和过滤器来解析"articlerresponse",但我不知道如何把这一切放在一起。此外,"articlerresponse"是由我从Retrofit得到的json生成的,所以我想使用RxJava会更好,因为我已经有了可观察对象,而不是在我的回调中嵌套for。
我认为你的意思是articlesResponse.comments是一个包含这些所有ArticleData的所有评论的列表,虽然我不认为将这些数据包装在一起并在客户端进行映射操作是一个好主意,这项工作应该在服务器上完成。
我想也许你的ArticlesResponse
的comments
域应该是一个List<Comments>
。
有了这些假设,下面的代码可以完成您想要的工作(我将它们放在TempTest
类中,并定义了您描述的接口,并模拟它以传递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);
}
});
}
}
对你的实际问题有点困惑,希望这能有所帮助。Retrofit可以为你返回一个Observable,这应该会使RxJava集成变得容易。例如,在你的服务中,你可以这样写:
@GET(<your endpoint>)
Observable<ArticlesResponse> getArticles();
并命名为:
<yourService>.getArticles()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedules.mainThread())
.subscribe() // manipulate how you want