在Reactive X Java中可以观察到变换集合

时间:2015-02-09 19:35:51

标签: java reactive-programming rx-java

我有一段代码,它使用ReactiveX的几个map语句将List [VideoDetails]块转换为VideoGrid:

feedService.loadVideoDetailsFeed(things)
            .map(new Func1<List<VideoDetails>, List<Video>>() {
                @Override
                public List<Video> call(List<VideoDetails> details) {
                    return Lists.transform(details, new Function<VideoDetails, Video>() {
                        @Override
                        public Video apply(VideoDetails input) {
                            return input.getVideo();
                        }
                    });
                }
            })
            .map(new Func1<List<Video>, VideoGrid>() {
                @Override
                public VideoGrid call(List<Video> videos) {
                    //stuff
                }
            })

如您所见,我在其中一个地图语句中使用Guava变换从List [VideoDetails]转到List [Video]。我认为通过ReactiveX有更好的方法来完成这种转换?我正在查看文档的transforming section,但我可能会对ReactiveX过于绿色以了解在这里使用的内容。

上面的代码段有效,如果可能,我宁愿以正确的方式进行。

3 个答案:

答案 0 :(得分:2)

保持rx风格,您可以使用以下示例:

修改

feedService.loadVideoDetailsFeed(things)
        .flatMap(new Func1<List<VideoDetails>, Observable<Video>>() {
            @Override
            public Observable<Video> call(List<VideoDetails> videoDetailsList) {
                return Observable.from(videoDetailsList).map(new Func1<VideoDetails, Video>() {
                    @Override
                    public Video call(VideoDetails videoDetails) {
                        return videoDetails.getVideo();
                    }
                });
            }
        })
        .toList();

答案 1 :(得分:1)

看起来你需要保持VideoInfo流的缓冲方面来创建VideoGrid。因此,如果是这种情况,那么在整个过程中保持Rx的唯一方法就是不必要地将这些子列表转换为可观察对象,然后映射/转换内部可观察对象,仅在创建VideoGrid时将它们折叠回列表。你现在这样做的方式可能是最务实的。

如果你碰巧使用Java 8,你可以抛弃Guava和内部类:

return details.stream().map(VideoDetails::getVideo).collect(Collectors.toList());

修改 这是一种留在Rx的方法

        feedService.loadVideoDetailsFeed(things)
               .flatMap(new Func1<List<VideoDetails>, Observable<List<Video>>>() {
                   @Override
                   public Observable<List<Video>> call(final List<VideoDetails> videoDeets) {
                       return Observable.from(videoDeets).map(new Func1<VideoDetails, Video>() {
                           @Override
                           public Video call(final VideoDetails videoDetails) {
                               return videoDetails.getVideo();
                           }
                       }).toList();
                   }
               })
               .map(new Func1<List<Video>, VideoGrid>() {
                   @Override
                   public VideoGrid call(List<Video> videos) {
                       return VideoGrid.fromListOfVideos(videos);
                   }
               });

这是一种产生更少垃圾的方法。实际的可观察查询更具可读性,但整体代码更多。

private static Func1<VideoDetails, Video> _getVideo = new Func1<VideoDetails, Video>() {
    @Override
    public Video call(final VideoDetails videoDetails) {
        return videoDetails.getVideo();
    }
};
private static Func1<List<VideoDetails>, Observable<List<Video>>> _mapVideoDetailsToVideos = new Func1<List<VideoDetails>, Observable<List<Video>>>() {
    @Override
    public Observable<List<Video>> call(final List<VideoDetails> videoDeets) {
        return Observable.from(videoDeets).map(_getVideo).toList();
    }
};
private static Func1<List<Video>, VideoGrid> _buildVideoGridFromVideos = new Func1<List<Video>, VideoGrid>() {
    @Override
    public VideoGrid call(List<Video> videos) {
        return VideoGrid.fromListOfVideos(videos);
    }
};

private static void yourFunction(final VideoDeetsSource feedService, String things) {
    feedService.loadVideoDetailsFeed(things)
               .flatMap(_mapVideoDetailsToVideos)
               .map(_buildVideoGridFromVideos);
}

答案 2 :(得分:1)

你能做什么:

  • Observable<List<VideoDetails>>开始,然后将其转换为Observable<VideoDetails>
  • 将此Observable<VideoDetails>转换为Observable<Video>
  • 最后一步:将此Observable<Video>转换为Observable<List<Video>>

使用RxJava(使用Java8语法)

非常容易
feedService.loadVideoDetailsFeed(things) // Observable<List<VideoDetails>>
           .flapMap(Observable::from) // Observable<VideoDetails>
           .map(details -> details.getVideo()) // Observable<Video>
           .toList() // Observable<List<Video>>
           .map(/* doYourStuff */)
           .subscribe();