如何在rxjava中使用toMap()获取索引

时间:2016-04-27 02:07:31

标签: java rx-java

我想将List更改为List,然后将Map映射为Map。 关键是“img”+ index,我该怎么做。

例如: 来自List [“a”,“b”,“c”] 映射{“img1”:“a”,“img2”:“b”,“img3”:“c”}

Observable.from((Bitmap[])bitmapList.toArray())
            .subscribeOn(Schedulers.io())
            .map(new Func1<Bitmap, String>() {
                @Override
                public String call(Bitmap bitmap) {
                    return doSomething(bitmap);
                }
            })
            .toMap(new Func1<String, String>() {
                @Override
                public String call(String s) {
                    return "img"; // how to got the index
                }
            })
            ...;

1 个答案:

答案 0 :(得分:2)

为了将值与索引组合,您需要一些内部状态:您需要跟踪流中的计数器。您可以使用scan运算符执行此操作。因为你需要跟踪计数器的实际值,我们首先需要引入一个可以包含两个值的简单类:

private static class Tuple<T, S> {

    final T first;
    final S second;

    Tuple(T k, S v) {
        this.first = k;
        this.second = v;
    }
}

scan运算符需要两个参数:状态的初始值和采用先前状态和新值的累加器函数,并将它们转换为新状态。初始状态很简单,它是空字符串("")和初始索引的组合(取决于您要启动的索引,01。累加器是现在很容易:它接受新值并从前一个状态递增计数器并将它们组合成一个新的Tuple

因为初始状态不是你想在这里看到的,你需要做一个skip(1)来摆脱第一个发射的元素。

最后你可以做toMap,但你需要带有两个参数的版本:keySelectorvalueSelector,你可以从{{1}获得密钥和值分别。

最终代码如下:

Tuple

请注意,public static void main(String[] args) { Observable.from(Arrays.asList("a", "b", "c")) .scan(new Tuple<>("", 0), (tuple, s) -> new Tuple<>(s, tuple.second + 1)) .skip(1) .toMap(tuple -> "img" + tuple.second, tuple -> tuple.first) .subscribe(System.out::println); } scan的这种组合实际上是skip,因为它在例如RxScala中被调用。 Java没有语言中的元组,因此您无法直接执行此操作,但您必须创建自己的zipWithIndex类才能使其正常工作。