Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 lambda Void argument

People also ask

Can lambda return void?

A return statement is not an expression in a lambda expression. We must enclose statements in braces ({}). However, we do not have to enclose a void method invocation in braces. The return type of a method in which lambda expression used in a return statement must be a functional interface.

What is lambda expression in Java 8 with example?

Lambda Expressions were added in Java 8. A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.

Can we write lambda without functional interface?

You do not have to create a functional interface in order to create lambda function.

Which is not a valid lambda expression?

Only A and B are valid.C is invalid because the lambda expression (Apple a) -> a. getWeight() has the signature (Apple) -> Integer, which is different than the signature of the method test defined in Predicate : (Apple) -> boolean.


Use Supplier if it takes nothing, but returns something.

Use Consumer if it takes something, but returns nothing.

Use Callable if it returns a result and might throw (most akin to Thunk in general CS terms).

Use Runnable if it does neither and cannot throw.


I think this table is short and usefull:

Supplier       ()    -> x
Consumer       x     -> ()
BiConsumer     x, y  -> ()
Callable       ()    -> x throws ex
Runnable       ()    -> ()
Function       x     -> y
BiFunction     x,y   -> z
Predicate      x     -> boolean
UnaryOperator  x1    -> x2
BinaryOperator x1,x2 -> x3

As said on the other answers, the appropriate option for this problem is a Runnable


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

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

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.


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 method to override the inherited parameterized method Void execute(Void), delegating the call to the simpler method void execute().

The result is that it's much simpler to use:

Command c = () -> System.out.println("Do nothing!");

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:

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