Rx java Rx-将数字列表减少为一系列(数字、计数)

Rx java Rx-将数字列表减少为一系列(数字、计数),rx-java,Rx Java,假设我们有一系列数字: 0,0,0,0,1,1,2,2,3,4,4,0,0,0,1,1 我正在寻找Rx observable,它可以将这个序列简化为包含(元素、组计数、元素的组计数)的对。因此,上述内容将成为: (0,4)//出现前4个“0” (1,2)//然后有两个“1” (2,3)//接着是三个“2”,一个接一个 (3,1)//出现一次“3” (4,3)//三个“4” (0,4)//四个零 (2,1)//和两个“1” 我还在学习,不能真正掌握这一点。我怀疑collect可能会有所帮助,但

假设我们有一系列数字:

0,0,0,0,1,1,2,2,3,4,4,0,0,0,1,1

我正在寻找Rx observable,它可以将这个序列简化为包含(元素、组计数、元素的组计数)的对。因此,上述内容将成为:

(0,4)//出现前4个“0”
(1,2)//然后有两个“1”
(2,3)//接着是三个“2”,一个接一个
(3,1)//出现一次“3”
(4,3)//三个“4”
(0,4)//四个零
(2,1)//和两个“1”


我还在学习,不能真正掌握这一点。我怀疑collect可能会有所帮助,但甚至找不到一个好的例子……

你可以通过
发布
缓冲区
来实现效果,但我觉得它太复杂了。我发现在数据和缓冲区更改决策位于一个位置的情况下编写运算符要简单得多:

public final class BufferUntilChanged<T, U> 
implements Operator<List<T>, T> {
    final Func1<? super T, U> keySelector;

    public BufferUntilChanged(Func1<? super T, U> keySelector) {
        this.keySelector = keySelector;
    }

    @Override
    public Subscriber<? super T> call(Subscriber<? super List<T>> t) {
        BufferUntilChangedSubscriber<T, U> parent = 
                new BufferUntilChangedSubscriber<>(t, keySelector);
        t.add(parent);
        return parent;
    }

    static final class BufferUntilChangedSubscriber<T, U> 
    extends Subscriber<T> {
        final Func1<? super T, U> keySelector;
        final Subscriber<? super List<T>> actual;

        List<T> list;
        U lastKey;

        public BufferUntilChangedSubscriber(
                Subscriber<? super List<T>> actual,
                Func1<? super T, U> keySelector) {
            this.keySelector = keySelector;
            this.actual = actual;
        }

        @Override
        public void onNext(T t) {
            U u;

            try {
                u = keySelector.call(t);
            } catch (Throwable e) {
                unsubscribe();
                actual.onError(e);
                return;
            }

            boolean doRequest;
            if (list == null) {
                list = new ArrayList<>();
                lastKey = u;
                doRequest = true;
            } else
            if (!Objects.equals(lastKey, u)) {
                actual.onNext(list);
                list = new ArrayList<>();
                doRequest = false;
            } else {
                doRequest = true;
            }
            list.add(t);

            lastKey = u;

            if (doRequest) {
                request(1);
            }
        }

        @Override
        public void onError(Throwable e) {
            actual.onError(e);
        }

        @Override
        public void onCompleted() {
            if (list != null) {
                actual.onNext(list);
            }
            actual.onCompleted();
        }
    }

}
公共最终类BufferUntlChanged
机具操作员{

最后一个Func1Ah,你又来了。然后答案一定是好的。但让我先检查一下。在检查之前,我必须先将你的代码转换为Kotlin.Hmmm…这肯定是件小事,但我如何修复“source.lift(new BufferUntilChanged(v->v))?v->v似乎不正确(而且无论如何都不会编译)我是从Eclipse复制的,Eclipse编译得很好。也许这是javac中的类型推断错误之一。试试
(整数v)->v
,或者把它分解出来
Func1 f=v->v;
你一定是个天才。这是一段很棒的代码,希望我能理解它。无论如何,作为奖励,这里是Kotlin中的示例代码:source.lift(BufferUntilChanged({v->v})).map{list->arrayOf(list[0],list.size)}.subscribe{v->println(Arrays.toString(v))}
    public static void main(String[] args) {
        Observable<Integer> source = Observable.from(
                new Integer[] { 
                        0,0,0,0,
                        1,1,
                        2,2,2,
                        3,
                        4,4,4,
                        0,0,0,0,
                        1,1 });

        source.lift(new BufferUntilChanged<>(v -> v))
        .map(list -> new Integer[] { 
                list.get(0), list.size() 
        })
        .subscribe(v -> 
            System.out.println(Arrays.toString(v)));
    }