gpt4 book ai didi

java - 在 Stream.map() 中将 Consumer 转换为 Runnable

转载 作者:搜寻专家 更新时间:2023-11-01 01:16:00 24 4
gpt4 key购买 nike

我正在尝试将 Consumer 转换为 Runnable。以下代码不会在 Eclipse IDE 中生成任何编译器错误。

Consumer<Object> consumer;
Runnable runnable;
Object value;

...
runnable = () -> consumer.accept(value);

以下代码在 Eclipse IDE 中生成编译器错误。

ArrayList<Consumer<Object>> list;
Object value;

...

list.
stream().
map(consumer -> () -> consumer.accept(value));

错误是:

Type mismatch: Can not convert from Stream<Object> to <unknown>.
The target type of this expression must be a functional interface.

我如何帮助编译器将 Consumer 转换为 Runnable

下面的代码解决了这个问题,但是非常冗长。

map(consumer -> (Runnable) (() -> consumer.accept(value)));

有没有更简洁的方法来做到这一点?我知道我可以创建一个接受 Consumer 并返回 Runnable 的静态方法,但我不认为那样更简洁。

最佳答案

如果考虑表达式,错误消息是正常的:

list.stream().map(consumer -> () -> consumer.accept(value))
^--------------------------^
what is the type of that?

问题在于编译器无法确定表达式 () -> consumer.accept(value) 的目标类型。它当然可以是 Runnable,但也可以是 MyAwesomeInterface 声明为:

@FunctionalInterface
interface MyAwesomeInterface { void foo(); }

事实上,它可以符合任何声明不带参数且不返回值的函数式方法的函数式接口(interface)。因此,这会导致编译错误。

当您将 lambda 表达式显式存储在 Runnable 中时没有错误:

Runnable runnable = () -> consumer.accept(value);

因为,编译器知道该 lambda 的目标类型是 Runnable


当您考虑以下问题时,问题会更加模糊:

List<Runnable> runnables = list.stream()
.map(consumer -> () -> consumer.accept(value))
.collect(Collectors.toList());

有人可能会争辩说,编译器可能能够推断出该表达式的目标类型是 Runnable,因为我们正在将其收集到 Runnable 列表中。但是,it doesn't并且您必须稍微帮助编译器并明确告诉编译器 Stream 元素是 Runnable:

List<Runnable> runnables = list.stream()
.<Runnable> map(consumer -> () -> consumer.accept(value))
.collect(Collectors.toList());

关于java - 在 Stream.map() 中将 Consumer 转换为 Runnable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35489967/

24 4 0