执行Observables Map

时间:2017-11-01 14:38:21

标签: java java-8 hashmap rx-java

是否有更优雅的方式来执行Map<K, Observable<V>>转换为Map<K, V>

我找到了以下方法:

@Test
public void test() {
    final ImmutableMap<String, Observable<Integer>> map = ImmutableMap.of(
        "1", Observable.just(1),
        "2", Observable.just(2),
        "3", Observable.just(3)
    );

    Map<String, Integer> result = new HashMap<>(map.size());

    final Integer execRes = map.entrySet()
        .stream()
        .map(entry -> {
            entry.getValue().subscribe(res -> result.put(entry.getKey(), res));
            return entry.getValue();
        })
        .reduce(Observable::concat).get().toBlocking().last();

    Assert.assertTrue(execRes == 3);
    Assert.assertTrue(1 == result.get("1"));
    Assert.assertEquals("{1=1, 2=2, 3=3}", result.toString());
}

P.S。使用rxjava-1.1.7并且Observable代码必须并行(同时)

运行

2 个答案:

答案 0 :(得分:1)

这个怎么样?使用Java 8流:

Map<String, Integer> result = map.entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().toBlocking().first()));

使用Rx:

Map<String, Integer> result = Observable.from(map.entrySet())
        .toMap(Map.Entry::getKey, a -> a.getValue().toBlocking().first()).toBlocking().first();

答案 1 :(得分:0)

我发现您使用的是Guava,因此我们可以在Guava中使用一些有意义的方法。

即使值不是单一的,我们也可以将其转换为Multimap

这是我的代码:

import java.util.Map;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;

import rx.Observable;

public class Q47057374 {
  public static void main(String[] args) {
    final ImmutableMap<String, Observable<Integer>> map = ImmutableMap.of(
        "1", Observable.just(1),
        "2", Observable.just(2),
        "3", Observable.just(3));
    System.out.println(toMap(map));
    final ImmutableMap<String, Observable<Integer>> multimap = ImmutableMap.of(
        "1", Observable.just(1, 2, 3),
        "2", Observable.just(4, 5, 6),
        "3", Observable.just(7, 8, 9));
    System.out.println(toMutimap(multimap));
  }

  public static <K, V> Map<K, V> toMap(Map<K, Observable<V>> map) {
    return Maps.transformValues(map, o -> o.toSingle().toBlocking().value());
  }

  public static <K, V> Multimap<K, V> toMutimap(Map<K, Observable<V>> map) {
    ArrayListMultimap<K, V> multimap = ArrayListMultimap.create();
    map.forEach((k, vo) -> vo.forEach(v -> multimap.put(k, v)));
    return multimap;
  }
}

输出:

{1=1, 2=2, 3=3}
{1=[1, 2, 3], 2=[4, 5, 6], 3=[7, 8, 9]}