How to pass a function as a parameter in Java?
Java 8 and above
Using Java 8+ lambda expressions, if you have a class or interface with only a single abstract method (sometimes called a SAM type), for example:
public interface MyInterface {
String doSomething(int param1, String param2);
}
then anywhere where MyInterface is used, you can substitute a lambda expression:
class MyClass {
public MyInterface myInterface = (p1, p2) -> { return p2 + p1; };
}
For example, you can create a new thread very quickly:
new Thread(() -> someMethod()).start();
And use the method reference syntax to make it even cleaner:
new Thread(this::someMethod).start();
Without lambda expressions, these last two examples would look like:
new Thread(new Runnable() { someMethod(); }).start();
Before Java 8
A common pattern would be to 'wrap' it within an interface, like Callable
, for example, then you pass in a Callable:
public T myMethod(Callable<T> func) {
return func.call();
}
This pattern is known as the Command Pattern.
Keep in mind you would be best off creating an interface for your particular usage. If you chose to go with callable, then you'd replace T above with whatever type of return value you expect, such as String.
In response to your comment below you could say:
public int methodToPass() {
// do something
}
public void dansMethod(int i, Callable<Integer> myFunc) {
// do something
}
then call it, perhaps using an anonymous inner class:
dansMethod(100, new Callable<Integer>() {
public Integer call() {
return methodToPass();
}
});
Keep in mind this is not a 'trick'. It's just java's basic conceptual equivalent to function pointers.
Java Pass Method as Parameter
Edit: as of Java 8, lambda expressions are a nice solution as other answers have pointed out. The answer below was written for Java 7 and earlier...
Take a look at the command pattern.
// NOTE: code not tested, but I believe this is valid java...
public class CommandExample
{
public interface Command
{
public void execute(Object data);
}
public class PrintCommand implements Command
{
public void execute(Object data)
{
System.out.println(data.toString());
}
}
public static void callCommand(Command command, Object data)
{
command.execute(data);
}
public static void main(String... args)
{
callCommand(new PrintCommand(), "hello world");
}
}
Edit: as Pete Kirkham points out, there's another way of doing this using a Visitor. The visitor approach is a little more involved - your nodes all need to be visitor-aware with an acceptVisitor()
method - but if you need to traverse a more complex object graph then it's worth examining.
How to pass a function as a parameter in java
Java 8 was shipped with enormous number of functional interfaces. You can use one of those to describe the expected function to be passed as parameter in your method.
In your case, for passing a function which excepts a single double
parameter and applys a logic, use java.util.function.DoubleUnaryOperator:
static double foo(DoubleUnaryOperator fn){
double aNumber = 2.0;
return fn.applyAsDouble(aNumber);
}
And then create a lambda (or an object which implements DoubleUnaryOperator
) and pass it to the foo
method:
foo(d -> d * 3);
or
public class Fn implements DoubleUnaryOperator {
@Override
public double applyAsDouble(double d) {
return d * 3;
}
}
How to pass a function as an parameter to another function
No, you can't pass methods.
But there is a simple workaround: pass a Runnable.
void myFunction(boolean coondition, Runnable function)
{
if(condition) {
function.run();
}
}
and call it like this: (using the old syntax)
myFunction(condition, new Runnable() {
@Override
public void run() {
otherFunction();
}
});
or using the new lambda syntax in Java 8 (which is mostly shorthand for the above):
myFunction(condition, () -> {otherFunction();}}
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 function parameter in Java 8 in stream groupby
Take a look at the documentation for groupingBy.
You need a Function<? super T,? extends K> classifier
as the type, or something more specific depending on how your ReportProfitAnalysis
and reportProfitResult
look.
For example:
private void MapResult(Function<? super ReportProfitAnalysis, ?> func) {
reportProfitResult = reportProfits.stream()
.collect(Collectors.groupingBy(func));
}
You can pass the grouping function
Function<? super ReportProfitAnalysis, ?> func = ReportProfitAnalysis::getStatisticTime;
Note that the reportProfitResult
here would be defined as Map<?, List<ReportProfitAnalysis>> reportProfitResult
How to pass a function as parameter in java to run it multiple times
You could try reflection
here:
E.g:
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
Method method = Test.class.getMethod("myFunction");
boolean didwork = retry(method, 5);
if (didwork) {
System.out.println("I found my stuff");
} else {
System.out.println("I didn't found my stuff");
}
}
public static boolean retry(Method method, int loopTry)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
boolean success = false;
for (int i = 0; i < loopTry; i++) {
success = (Boolean) method.invoke(null);
if (success) {
break;
}
}
return success;
}
public static boolean myFunction() {
boolean found = false;
//do stuff
if(stuff){
found = true;
}
return found;
}
Related Topics
What Are the Rules For Evaluation Order in Java
How to Implement a Tree Data-Structure in Java
Why Is the Java Main Method Static
Java Process With Input/Output Stream
How to Add to List≪? Extends Number≫ Data Structures
What's the Reason I Can't Create Generic Array Types in Java
How to Update a Jfreechart'S Appearance After It's Been Made Visible
Initialization of an Arraylist in One Line
How to Use Different Certificates on Specific Connections
How to Handle Cors Using Jax-Rs With Jersey
How to Pretty Print Xml from Java
Want Current Date and Time in "Dd/Mm/Yyyy Hh:Mm:Ss.Ss" Format
What Is the Memory Consumption of an Object in Java
Getting a File'S Md5 Checksum in Java
Unicode Equivalents For \W and \B in Java Regular Expressions