java - 从函数创建流的最简单方法

标签 java java-8 java-stream

Stream<T> 基于 Spliterator<T> 提供的内部迭代方法,后者又将迭代委托(delegate)给 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);
}

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

最佳答案

由于没有接受函数的内置功能,因此无法创建类型,尽管它不一定是内部类。例如

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);

但是既然你已经明确了你的目标是实现自定义的中间操作,那么上面的方案并不适用。最好使用内部类的另一种替代方法,即专用的顶级类。

大多数这些操作,如您提到的示例,要么执行状态,要么必须指定特征或更复杂的估计大小,您无法使用单个函数来表达这些操作。

关于java - 从函数创建流的最简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42997456/

相关文章:

java - 使用 Java 8 在列表中仅查找重复的字符串属性

Java 8 - 默认方法 - 对遗留代码的关注

Java Stream Api 反转数据结构并标准化变量

java - 你能把一个流分成两个流吗?

java - 在 Java 中解析持续时间的最简洁方法

java - 在android中请求最近的城市

java - eclipse:调试以编程方式启动的进程

java - 句子构成 : Punctuation checks in java

java - 在 Java 8 中使用 Function 抽象 try/catch

java - 使用流处理异常