Java 8 lambda 空参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29945627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 lambda Void argument
提问by Wickoo
Let's say I have the following functional interface in Java 8:
假设我在 Java 8 中有以下功能接口:
interface Action<T, U> {
U execute(T t);
}
And for some cases I need an action without arguments or return type. So I write something like this:
在某些情况下,我需要一个没有参数或返回类型的操作。所以我写了这样的东西:
Action<Void, Void> a = () -> { System.out.println("Do nothing!"); };
However, it gives me compile error, I need to write it as
但是,它给了我编译错误,我需要将其写为
Action<Void, Void> a = (Void v) -> { System.out.println("Do nothing!"); return null;};
Which is ugly. Is there any way to get rid of the Void
type parameter?
这是丑陋的。有没有办法摆脱Void
类型参数?
采纳答案by Matt
The syntax you're after is possible with a little helper function that converts a Runnable
into Action<Void, Void>
(you can place it in Action
for example):
你以后的语法可能与一个小帮手功能,其转换Runnable
成Action<Void, Void>
(你可以将它放在Action
为例):
public static Action<Void, Void> action(Runnable runnable) {
return (v) -> {
runnable.run();
return null;
};
}
// Somewhere else in your code
Action<Void, Void> action = action(() -> System.out.println("foo"));
回答by Konstantin Yovkov
The lambda:
拉姆达:
() -> { System.out.println("Do nothing!"); };
actually represents an implementation for an interface like:
实际上代表了一个接口的实现,如:
public interface Something {
void action();
}
which is completely different than the one you've defined. That's why you get an error.
这与您定义的完全不同。这就是为什么你会得到一个错误。
Since you can't extend your @FunctionalInterface
, nor introduce a brand new one, then I think you don't have much options. You can use the Optional<T>
interfaces to denote that some of the values (return type or method parameter) is missing, though. However, this won't make the lambda body simpler.
既然你不能扩展你的@FunctionalInterface
,也不能引入一个全新的,那么我认为你没有太多选择。不过,您可以使用Optional<T>
接口来表示某些值(返回类型或方法参数)丢失。但是,这不会使 lambda 主体更简单。
回答by pnadczuk
I don't think it is possible, because function definitions do not match in your example.
我认为这是不可能的,因为函数定义在您的示例中不匹配。
Your lambda expression is evaluated exactly as
您的 lambda 表达式的计算方式完全相同
void action() { }
whereas your declaration looks like
而你的声明看起来像
Void action(Void v) {
//must return Void type.
}
as an example, if you have following interface
例如,如果您有以下界面
public interface VoidInterface {
public Void action(Void v);
}
the only kind of function (while instantiating) that will be compatibile looks like
唯一一种兼容的函数(在实例化时)看起来像
new VoidInterface() {
public Void action(Void v) {
//do something
return v;
}
}
and either lack of return statement or argument will give you a compiler error.
并且缺少 return 语句或参数会给你一个编译器错误。
Therefore, if you declare a function which takes an argument and returns one, I think it is impossible to convert it to function which does neither of mentioned above.
因此,如果您声明一个接受一个参数并返回一个参数的函数,我认为不可能将其转换为不执行上述任何一项的函数。
回答by fabian
That is not possible. A function that has a non-void return type (even if it's Void
) has to return a value. However you could add static methods to Action
that allows you to "create" a Action
:
这是不可能的。具有非 void 返回类型(即使它是Void
)的函数必须返回一个值。但是,您可以添加静态方法以Action
允许您“创建”一个Action
:
interface Action<T, U> {
U execute(T t);
public static Action<Void, Void> create(Runnable r) {
return (t) -> {r.run(); return null;};
}
public static <T, U> Action<T, U> create(Action<T, U> action) {
return action;
}
}
That would allow you to write the following:
这将允许您编写以下内容:
// create action from Runnable
Action.create(()-> System.out.println("Hello World")).execute(null);
// create normal action
System.out.println(Action.create((Integer i) -> "number: " + i).execute(100));
回答by Jord?o
You can create a sub-interface for that special case:
您可以为这种特殊情况创建一个子接口:
interface Command extends Action<Void, Void> {
default Void execute(Void v) {
execute();
return null;
}
void execute();
}
It uses a default methodto override the inherited parameterized method Void execute(Void)
, delegating the call to the simpler method void execute()
.
它使用默认方法覆盖继承的参数化方法Void execute(Void)
,将调用委托给更简单的方法void execute()
。
The result is that it's much simpler to use:
结果是使用起来要简单得多:
Command c = () -> System.out.println("Do nothing!");
回答by MCHAppy
Add a static method inside your functional interface
在您的功能接口中添加一个静态方法
package example;
interface Action<T, U> {
U execute(T t);
static Action<Void,Void> invoke(Runnable runnable){
return (v) -> {
runnable.run();
return null;
};
}
}
public class Lambda {
public static void main(String[] args) {
Action<Void, Void> a = Action.invoke(() -> System.out.println("Do nothing!"));
Void t = null;
a.execute(t);
}
}
Output
输出
Do nothing!
回答by SlavaL
Just for reference which functional interface can be used for method reference in cases method throws and/or returns a value.
仅供参考,在方法抛出和/或返回值的情况下,哪个功能接口可用于方法引用。
void notReturnsNotThrows() {};
void notReturnsThrows() throws Exception {}
String returnsNotThrows() { return ""; }
String returnsThrows() throws Exception { return ""; }
{
Runnable r1 = this::notReturnsNotThrows; //ok
Runnable r2 = this::notReturnsThrows; //error
Runnable r3 = this::returnsNotThrows; //ok
Runnable r4 = this::returnsThrows; //error
Callable c1 = this::notReturnsNotThrows; //error
Callable c2 = this::notReturnsThrows; //error
Callable c3 = this::returnsNotThrows; //ok
Callable c4 = this::returnsThrows; //ok
}
interface VoidCallableExtendsCallable extends Callable<Void> {
@Override
Void call() throws Exception;
}
interface VoidCallable {
void call() throws Exception;
}
{
VoidCallableExtendsCallable vcec1 = this::notReturnsNotThrows; //error
VoidCallableExtendsCallable vcec2 = this::notReturnsThrows; //error
VoidCallableExtendsCallable vcec3 = this::returnsNotThrows; //error
VoidCallableExtendsCallable vcec4 = this::returnsThrows; //error
VoidCallable vc1 = this::notReturnsNotThrows; //ok
VoidCallable vc2 = this::notReturnsThrows; //ok
VoidCallable vc3 = this::returnsNotThrows; //ok
VoidCallable vc4 = this::returnsThrows; //ok
}
回答by x1a0
Use Supplier
if it takes nothing, but returns something.
使用Supplier
如果它需要什么,但回报的东西。
Use Consumer
if it takes something, but returns nothing.
Consumer
如果它需要一些东西,但什么都不返回,请使用。
Use Callable
if it returns a result and might throw (most akin to Thunk
in general CS terms).
使用Callable
如果它返回一个结果,并可能会抛出(最类似于Thunk
一般的CS而言)。
Use Runnable
if it does neither and cannot throw.
使用Runnable
如果它既不并不能扔。