RxJava2 - 将对象处理结果分组到 Map<String, List<Object>>

RxJava2 - group results of objects processing into the Map<String, List<Object>>

我有一个 REST URI 列表,并且有一个方法可以 returns 传递的 URI 的一些值:

String searchForValueBy(RestURI uri);

例如,我们有以下列表:

List<RestURI> restUriList = List.of(uri1, uri2, uri3, uri4, uri5);

searchForValueBy returns 每个 URI 的以下值:

uri1 : "1"
uri2 : "2"
uri3 : "1"
uri4 : "1"
uri5 : "2"

我想要实现的是将 URI 和值分组到以下映射中 Map<String, List<RestURI>>

我做了以下实现,但它使用了两种不同的方法——传统方法和反应式方法:

Map<String, List<RestURI>> valueToUriMap = new HashMap<>();
Observable.fromIterable(restUriList)
            .flatMapCompletable(uri -> searchForValueBy(uri))
                    .flatMapCompletable(value -> {
                        valueToUriMap.computeIfAbsent(value, key -> new ArrayList<>()).add(uri);
                        return Completable.complete();
                    }))
            .andThen(/*work with valueToUriMap*/)

是否可以通过像 groupBy 这样的某种分组来实现相同的目的?

这里是复制和播放的工作示例:

public static void main(String[] args) {
        final List<RestUri> restUriList = List.of(
                new RestUri("uri1", "1"),
                new RestUri("uri2", "2"),
                new RestUri("uri3", "1"),
                new RestUri("uri4", "1"),
                new RestUri("uri5", "2"));

        Map<String, List<RestUri>> valueToUriMap = new HashMap<>();
        Observable.fromIterable(restUriList)
                .flatMapCompletable(uri -> searchForValueBy(uri)
                        .flatMapCompletable(value -> {
                            valueToUriMap.computeIfAbsent(value, key -> new ArrayList<>()).add(uri);
                            return Completable.complete();
                        })).subscribe();
//                .andThen(/*work with valueToUriMap*/)

        valueToUriMap.keySet().forEach(key -> System.out.println("Key: " + key + ", Value: " + valueToUriMap.get(key)));
    }

    public static Single<String> searchForValueBy(RestUri uri) {
        return Single.just(uri.getValue());
    }

    static class RestUri {
        String uri;
        String value;

        public RestUri(String uri, String value) {
            this.uri = uri;
            this.value = value;
        }

        public String getUri() {
            return uri;
        }

        public String getValue() {
            return value;
        }

        @Override
        public String toString() {
            return uri;
        }
    }

在@akarnokd 评论后更新

似乎 toMultimap 可以解决问题,但最后它似乎是一个单条目映射列表,而不是带有一堆 key:value 对的映射:

Observable<Single<Map<String, Collection<RestUri>>>> result = Observable.fromIterable(restUriList)
            .map(uri -> searchForValueBy(uri)
                    .toMultimap(key -> key, value -> uri));

试试这个:

Observable.fromIterable(restUriList)
          .flatMapSingle(uri -> 
                searchForValueBy(uri)
                .map(v -> new RestUri(uri.getUri(), v))
          )
          .toMultimap(RestUri::getValue, RestUri::getUri))