解释如何将lambda分配给Iterable [英] Explain how this lambda can be assigned to an Iterable

查看:132
本文介绍了解释如何将lambda分配给Iterable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一些聪明的代码,用于将Iterator转换为来自Karol的Stream 这篇文章。我必须承认,我不完全理解如何在以下代码中将lambda分配给 Iterable 类型...

I came across some clever code to convert an Iterator to a Stream from Karol on this post. I have to admit that I don't completely understand how the lambda is allowed to be assigned to the Iterable type in the following code...

static <T> Stream<T> iteratorToFiniteStream(final Iterator<T> iterator) {
    final Iterable<T> iterable = () -> iterator;
    return StreamSupport.stream(iterable.spliterator(), false);
}

我决定编写自己的小测试以确保编译和执行,确实如此。

I decided to write my own small test to ensure that it compiles and executes, and it does.

public void printsStream_givenIterator()
{
    Iterator<String> iterator = Arrays.asList("a", "b", "c").iterator();
    final Iterable<String> iterable = () -> iterator;
    StreamSupport.stream(iterable.spliterator(), false).forEach(s -> System.out.println(s));
}

// prints: abc

我的理解是lambda () - > iterator 充当供应商功能。

My understanding is that the lambda () -> iterator is acting as a Supplier function.

Iterable 不是 FunctionalInterface 那么如何分配这个lambda?

Iterable isn't a FunctionalInterface so how can it be assigned this lambda?

推荐答案

() - >迭代器 充当供应商函数。可以将Lambda表达式分配给任何一致的功能接口类型。并且不需要使用 @FunctionalInterface 注释功能接口。您可以使用lambda表达式创建 Iterable ,这将实现 Iterable.iterator()方法,即只有 abstract 该接口的方法。但是,通过每次返回相同的 Iterator 实例来实现它可能违反了能够多次迭代此对象的期望(这是为什么 Stream 未实现 Iterable 尽管有一个 iterator()方法)。

() -> iterator is not "acting as a Supplier function". Lambda expressions can be assigned to any congruent functional interface type. And there is no requirement for a functional interface to be annotated with @FunctionalInterface. You can create an Iterable with a lambda expression, which will implement the Iterable.iterator() method, which is the only abstract method of that interface. However, implementing it by returning the same Iterator instance each time may violate the expectation of being able to iterate this object multiple times (which is the reason why Stream doesn’t implement Iterable despite having an iterator() method).

这个解决方案可以在这个狭窄的环境中工作,但不是聪明。

This solution will work in this narrow context, but isn’t clever.

序列

final Iterable<T> iterable = () -> iterator; … iterable.spliterator()

Spliterators.spliteratorUnknownSize之前引入一个额外的步骤(iterator,0),这是默认方法已实施。

just introduces an additional step before Spliterators.spliteratorUnknownSize(iterator, 0), which is how the default method of Iterable.spliterator() is implemented.

所以

static <T> Stream<T> iteratorToFiniteStream(final Iterator<T> iterator) {
    final Iterable<T> iterable = () -> iterator;
    return StreamSupport.stream(iterable.spliterator(), false);
}

只是效率较低的

static <T> Stream<T> iteratorToFiniteStream(final Iterator<T> iterator) {
    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
}

如果你将它与Q& A的接受答案进行比较你就得到了链接,您会看到它正是如此,但该答案有机会传递特定的特征而不是 0

If you compare this to the accepted answer of the Q&A you’ve linked, you’ll see that it is exactly that, but that answer takes the opportunity of passing specific characteristics instead of 0.

这篇关于解释如何将lambda分配给Iterable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆