使用带有Lambda的JDK8压缩流(java.util.stream.Streams.zip)


问题内容

在带有lambda b93的JDK 8中,b93中有一个类java.util.stream.Streams.zip可用于对流进行zip处理(这在Dhananjay Nene的Exploring Java8 Lambdas。Part 1教程中进行了说明)。该功能:

创建一个惰性和顺序组合的Stream,其元素是两个流的元素组合的结果。

然而,在b98中,这种现象消失了。实际上,在b98的java.util.stream中Streams甚至无法访问该类。

此功能是否已移动,如果是,我如何使用b98简洁地压缩流?

我想到的应用程序是此Shen的java实现中的,我在其中替换了zip功能。

static <T> boolean every(Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred)
static <T> T find(Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred)

具有相当冗长的代码的功能(不使用b98的功能)。


问题答案:

我也需要它,因此我只是从b93中获取了源代码并将其放在“ util”类中。我必须对其稍作修改以使用当前的API。

供参考,以下是工作代码(风险自负…):

public static<A, B, C> Stream<C> zip(Stream<? extends A> a,
                                     Stream<? extends B> b,
                                     BiFunction<? super A, ? super B, ? extends C> zipper) {
    Objects.requireNonNull(zipper);
    Spliterator<? extends A> aSpliterator = Objects.requireNonNull(a).spliterator();
    Spliterator<? extends B> bSpliterator = Objects.requireNonNull(b).spliterator();

    // Zipping looses DISTINCT and SORTED characteristics
    int characteristics = aSpliterator.characteristics() & bSpliterator.characteristics() &
            ~(Spliterator.DISTINCT | Spliterator.SORTED);

    long zipSize = ((characteristics & Spliterator.SIZED) != 0)
            ? Math.min(aSpliterator.getExactSizeIfKnown(), bSpliterator.getExactSizeIfKnown())
            : -1;

    Iterator<A> aIterator = Spliterators.iterator(aSpliterator);
    Iterator<B> bIterator = Spliterators.iterator(bSpliterator);
    Iterator<C> cIterator = new Iterator<C>() {
        @Override
        public boolean hasNext() {
            return aIterator.hasNext() && bIterator.hasNext();
        }

        @Override
        public C next() {
            return zipper.apply(aIterator.next(), bIterator.next());
        }
    };

    Spliterator<C> split = Spliterators.spliterator(cIterator, zipSize, characteristics);
    return (a.isParallel() || b.isParallel())
           ? StreamSupport.stream(split, true)
           : StreamSupport.stream(split, false);
}