Full outer join of two ordered observables

孤者浪人 提交于 2019-12-02 00:17:40

There is no single operator for this but it is possible to compose the behavior from standard and extension operators:

static abstract class Pair implements Comparable<Pair> { 
    int value;

    @Override
    public int compareTo(Pair o) {
        return Integer.compare(value, o.value);
    }
}

static final class Left extends Pair {
    Left(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "[" + value + ", _]";
    }
}

static final class Right extends Pair {
    Right(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "[_, " + value + "]";
    }
}

static final class Both extends Pair {
    Both(int value) {
        this.value = value;
    }

    @Override
    public int hashCode() {
        return value;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Both) {
            return ((Both)obj).value == value;
        }
        return false;
    }

    @Override
    public String toString() {
        return "[" + value + ", " + value + "]";
    }
}

@SuppressWarnings("unchecked")
@Test
public void test() {
    Flowable<Integer> a = Flowable.just(0, 2, 3, 6);
    Flowable<Integer> b = Flowable.just(1, 2, 3, 4, 5, 6);

    Flowable.defer(() -> {
        boolean[] skip = { false };
        return Flowables.<Pair>orderedMerge(
                a.<Pair>map(Left::new), b.<Pair>map(Right::new)
            )
            .distinctUntilChanged()
            .buffer(2, 1)
            .flatMapIterable(buf -> {
                if (skip[0]) {
                    skip[0] = false;
                    return Collections.emptyList();
                }
                if (buf.size() == 2) {
                    if (buf.get(0).value == buf.get(1).value) {
                        skip[0] = true;
                        return Collections.singletonList(new Both(buf.get(0).value));
                    }
                    return buf.subList(0, 1);
                }
                return buf;
            });
    })
    .subscribe(System.out::println);
}

where Flowables.orderedMerge is in the RxJava 2 Extensions library.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!