Java 8 lambda Void参数

Wic*_*koo 165 java lambda void java-8

假设我在Java 8中有以下功能接口:

interface Action<T, U> {
   U execute(T t);
}
Run Code Online (Sandbox Code Playgroud)

在某些情况下,我需要一个没有参数或返回类型的操作.所以我写这样的东西:

Action<Void, Void> a = () -> { System.out.println("Do nothing!"); };
Run Code Online (Sandbox Code Playgroud)

但是,它给了我编译错误,我需要把它写成

Action<Void, Void> a = (Void v) -> { System.out.println("Do nothing!"); return null;};
Run Code Online (Sandbox Code Playgroud)

这很难看.有没有办法摆脱Void类型参数?

x1a*_*1a0 437

Supplier如果没有任何东西,请使用,但返回一些东西

使用,Consumer如果它需要什么,但什么都不返回.

使用Callable如果它返回一个结果,并可能会抛出(最类似于Thunk一般的CS而言).

使用,Runnable如果它既不会,也不会扔.

  • 美丽的答案.简短而精确. (10认同)
  • 作为这个答案的完成,这不值得编辑:你也可以使用BiConsumer(取2,返回0),Function(取1,返回1)和BiFunction(取2,返回1).这些是最重要的知识 (8认同)
  • 是否有类似Callable的东西(会在其call()方法中引发异常)但需要任何返回值? (2认同)

Gab*_*ado 121

我认为这张表简短而有用:

Supplier       ()    -> x
Consumer       x     -> ()
Callable       ()    -> x throws ex
Runnable       ()    -> ()
Function       x     -> y
BiFunction     x,y   -> z
Predicate      x     -> boolean
UnaryOperator  x1    -> x2
BinaryOperator x1,x2 -> x3
Run Code Online (Sandbox Code Playgroud)

正如其他答案所说,这个问题的合适选项是 Runnable

  • 不要忘记 `BiConsumer: x, y -&gt; ()`! (8认同)
  • 我认为Java缺乏RunnableThrowingException () -&gt; () throws ex...(参见/sf/answers/3737862831/) (3认同)

Mat*_*att 98

您可以使用一个小的辅助函数来转换RunnableAction<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"));
Run Code Online (Sandbox Code Playgroud)

  • 这是你可以得到的最干净的解决方法,IMO,所以+1(或者在界面本身使用静态方法) (4认同)

Kon*_*kov 38

lambda:

() -> { System.out.println("Do nothing!"); };
Run Code Online (Sandbox Code Playgroud)

实际上代表了一个接口的实现,如:

public interface Something {
    void action();
}
Run Code Online (Sandbox Code Playgroud)

这与你定义的完全不同.这就是你得到错误的原因.

既然你不能扩展你的@FunctionalInterface,也不能推出一个全新的,那么我认为你没有太多的选择.但是,您可以使用Optional<T>接口来表示缺少某些值(返回类型或方法参数).但是,这不会使lambda体更简单.


Jor*_*dão 30

您可以为该特殊情况创建子接口:

interface Command extends Action<Void, Void> {
  default Void execute(Void v) {
    execute();
    return null;
  }
  void execute();
}
Run Code Online (Sandbox Code Playgroud)

它使用默认方法覆盖继承的参数化方法Void execute(Void),将调用委托给更简单的方法void execute().

结果是它使用起来更简单:

Command c = () -> System.out.println("Do nothing!");
Run Code Online (Sandbox Code Playgroud)


fab*_*ian 5

这是不可能的.具有非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;
   } 
}
Run Code Online (Sandbox Code Playgroud)

这将允许您编写以下内容:

// 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));
Run Code Online (Sandbox Code Playgroud)


小智 5

以与 @rado 相同的方式回答参数和描述:

/*----------------------
Represents an operation
that accepts two input
arguments and returns no
result.
*/
BiConsumer<T,U>         (T x, U y)  -> ()


/*----------------------
Represents a function
that accepts two arguments
and produces a result.
*/
BiFunction<T,U,R>       (T x, U y)   -> R z


/*----------------------
Represents an operation
upon two operands of the
same type, producing a
result of the same type
as the operands.
*/
BinaryOperator<T>       (T x1, T x2) -> T x3


/*----------------------
A task that returns a
result and may throw an
exception.
*/
Callable<V>             ()    -> V x   throws ex


/*----------------------
Represents an operation
that accepts a single
input argument and returns
no result.
*/
Consumer<T>             (T x)   -> ()


/*----------------------
Represents a function that
accepts one argument and
produces a result.
*/
Function<T,R>           (T x)   -> R y


/*----------------------
Represents a predicate
(boolean-valued function)
of one argument.
*/
Predicate<T>            (T x)   -> boolean


/*----------------------
Represents a portion of
executable code that
don't recieve parameters
and returns no result.
*/ 
Runnable                ()    -> ()


/*----------------------
Represents a supplier of
results.
*/
Supplier<T>             ()      -> T x

/*----------------------
Represents an operation 
on a single operand that
produces a result of the
same type as its operand.
*/
UnaryOperator<T>        (T x1)  -> T x2
Run Code Online (Sandbox Code Playgroud)

字体:

[1] https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html

[2] https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html

[3] https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html