从函数创建Stream的最简单方法

时间:2017-03-24 10:45:28

标签: java java-8 java-stream

Stream<T>基于Spliterator<T>提供的内部迭代方法,后者依次委托boolean tryAdvance(Consumer<? super T> action)实现的迭代。说实话:

Stream<T> ----> Spliterator<T> ----> boolean tryAdvance(Consumer<T>)

所以,我想有一些允许从Stream<T>创建Function<Consumer<T>, Boolean>的实用工具。请注意,Function<Consumer<T>, Boolean>具有相同的boolean tryAdvance(Consumer<T>)描述符,即Consumer<T> -> Boolean

我正在寻找辅助功能,例如(根据@ shmosel的comment更新):

static <T> Stream<T> stream(Predicate<Consumer<? super T>> moveNext) {
    Spliterator<T> iter = new AbstractSpliterator<T>(Long.MAX_VALUE, 0) {
        @Override
        public boolean tryAdvance(Consumer<? super T> action) {
            return moveNext.test(action);
        }
    };
    return StreamSupport.stream(iter, false);
}

这是我发现实现该实现的最简洁方式。然而,我仍然不喜欢使用匿名内部类。有没有最简单的选择?

1 个答案:

答案 0 :(得分:3)

由于没有接受函数的内置功能,因此无法创建类型,尽管它不必是内部类。 E.g。

public interface SingleFuncStream<T> extends Spliterator<T> {
    public static <T> Stream<T> stream(SingleFuncStream<T> f) {
        return StreamSupport.stream(f, false);
    }
    @Override default public Spliterator<T> trySplit() { return null; }
    @Override default public long estimateSize() { return Long.MAX_VALUE; }
    @Override default public int characteristics() { return ORDERED; }
}

可以像

一样使用
ListIterator<String> i = Arrays.asList("foo", "bar", "baz").listIterator(3);
SingleFuncStream.<String>stream(c -> {
    if(!i.hasPrevious()) return false;
    c.accept(i.previous());
    return true;
}).forEach(System.out::println);

但是现在您已经澄清了您的目标是实现自定义中间操作,上述解决方案并不合适。使用内部类的另一种替代方法(专用顶级类)可能更好。

这些操作中的大多数(如您提到的示例)都可以执行状态,或者必须指定特征或更复杂的估计大小,而这些大小是您无法使用单个函数表达的。