How to Define a Method Which Takes a Lambda as a Parameter in Java 8

How do I define a method which takes a lambda as a parameter in Java 8?

Lambdas are purely a call-site construct: the recipient of the lambda does not need to know that a Lambda is involved, instead it accepts an Interface with the appropriate method.

In other words, you define or use a functional interface (i.e. an interface with a single method) that accepts and returns exactly what you want.

Since Java 8 there is a set of commonly-used interface types in java.util.function.

For this specific use case there's java.util.function.IntBinaryOperator with a single int applyAsInt(int left, int right) method, so you could write your method like this:

static int method(IntBinaryOperator op){
return op.applyAsInt(5, 10);
}

But you can just as well define your own interface and use it like this:

public interface TwoArgIntOperator {
public int op(int a, int b);
}

//elsewhere:
static int method(TwoArgIntOperator operator) {
return operator.op(5, 10);
}

Then call the method with a lambda as parameter:

public static void main(String[] args) {
TwoArgIntOperator addTwoInts = (a, b) -> a + b;
int result = method(addTwoInts);
System.out.println("Result: " + result);
}

Using your own interface has the advantage that you can have names that more clearly indicate the intent.

Pass function as parameter to Lambda java 8

You can pass the Predicate used in the filter right to the method which is the only thing that differs in the methods.

Assuming offer.getOfferRows() returns List<OfferRow>, then:

public String getAllDangerousProductsName(Offer offer, Predicate<OfferRow> predicate) {
return offer.getOfferRows().stream()
.filter(predicate)
.map(row -> row.getItemInformation().getOfferTexts().getName())
.collect(Collectors.joining(","));
}

Usage becomes fairly simple:

// using lambda expression
String str1 = getAllDangerousProductsName(offer, row -> row.isDangerousGood());
String str2 = getAllDangerousProductsName(offer, row -> row.isBulkyGood());
// using method reference
String str1 = getAllDangerousProductsName(offer, OfferRow::isDangerousGood);
String str2 = getAllDangerousProductsName(offer, OfferRow::isBulkyGood);

How to pass a Java 8 lambda with a single parameter

Your lambda takes one parameter, but you only pass the lambda to executeLambda, not the value. If you want the lambda to capture the local variable, don't write it taking a parameter, but if you do really want it to take one parameter, you would write it like this:

import java.util.function.Consumer;

public static void main(String[] args) {
String message = "Hello World";
executeLambda(message, value -> print(value));
}

public static void executeLambda(String value, Consumer<String> lambda) {
lambda.accept(value);
}

If you want it to capture the value, then use Runnable, write the lambda as () -> print(value), and call it like runnable.run().

how to pass lambda expression with arguments as parameters in Java 8?

Your handleOperation method takes an object that implements Function, Operation::add (a method reference) doesn't qualify. Also, for two arguments, you'll need to use BiFunction instead.

Here's an example that should work:

public class LambdaExample {

public static Integer handleOperation(Integer x, Integer y, BiFunction<Integer, Integer, Integer> converter){
return converter.apply(x,y);
}

public static void main(String[] args){
handleOperation( 10,10, new Operation() ); // should return 20
}

}

class Operation implements BiFunction<Integer, Integer, Integer> {

public Integer apply(Integer x, Integer y){
return x+y;
}

}

Updated:

public class LambdaExample {

public static Integer handleOperation(Integer x, Integer y, BiFunction<Integer, Integer, Integer> converter){
return converter.apply(x,y);
}

public static void main(String[] args){
handleOperation( 10,10, Operation::add ); // should return 20
}

}

class Operation {

public static int add(Integer x, Integer y){
return x+y;
}

}

Java8 pass a method as parameter using lambda

You should provide a suitable functional interface which abstract method signature is compatible with your method reference signature. In your case it seems that Runnable instead of Function should be used:

public class MethodExecutor {
List<Runnable> listOfMethodsToExecute = new ArrayList<>();

//Add a new function to the list
public void addFunction(Runnable f){
if(f!=null){
listOfMethodsToExecute.add(f);
}
}

//Executes all the methods previously stored on the list
public void executeAll(){
listOfMethodsToExecute.forEach(Runnable::run);
}
}

Also note that in static main method this is not defined. Probably you wanted something like this:

me.addFunction(new Test()::aMethod);

Function.Function of Java 8 with multiple parameters

Function<Integer,Integer,Integer> f3 = (x,y) -> {return x + y};

is actually a BiFunction<Integer,Integer,Integer>

and

Function<Double> f4 = () -> {return Math.random()};

is a Supplier<Double>

If you need more create your own, like TriFunction<Integer,Integer,Integer,Integer> for example

Java: How to pass parameters into Thread method using lambda expression?

Your lambda can read final variables in the scope where it is defined.
So the easiest thing would be to make final variables for the things you want to pass into myMethod.

final int a = 1;
final int b = 2;
Thread myThread = new Thread(() -> { myMethod(a,b); });
myThread.start(); // don’t forget to execute it, just creating it won’t run the thread

Actually the variables can be “effectively final”, not technically final.
Make a variable and don’t change what’s in it, there isn’t a way for the lambda to detect changes in the variables. But it may be just as well to enforce it with final.

Otherwise don’t use a lambda, define a Runnable or Callable and pass in what it needs through the constructor.

It seems likely to me the real issue is not starting the thread as pointed out in the comments.

Operator '' cannot be applied to 'lambda parameter', 'int' in java

Map#entrySet returns a Set<Map.Entry<K,V>>. Set inherits removeIf from the Collection interface, which expects a Predicate<? super E>, namely a predicate with a single argument. E in this case is Map.Entry<K,V> (which is still only a single object, even though it holds two other values: a key and a value). Key and value can be accessed via getKey() and getValue() methods, respectively.

Your code is fixed easily:

testMap.entrySet().removeIf(entry -> entry.getValue() < 100);


Related Topics



Leave a reply



Submit