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 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.
Passing a method reference as parameter
You seem to want a Supplier
like
Double sumBy(Supplier<List<Double>> f) {
Double sum = 0.0;
for (Double price : f.get()) {
sum += price;
}
return sum;
}
Your List.of
syntax was giving me errors. So I did
List<Double> prices = Arrays.asList(1.00, 10.00, 100.00);
List<Double> pricesWithTax = Arrays.asList(1.22, 12.20, 120.00);
Then I tested like
public static void main(String[] args) throws IOException {
Order order = new Order();
double sum = order.sumBy(order::getPrices);
double sumWithTaxes = order.sumBy(order::getPricesWithTax);
System.out.printf("%.2f %.2f%n", sum, sumWithTaxes);
}
Outputs
111.00 133.42
Java pass method reference as parameter to other method
Your getX()
methods can be seen as a Function that accepts a DataStore instance and returns a float.
In Java 8 you can represent them with method references :
float[] aArray = getValuesAsArray(dataMap, DataStore::getA);
float[] bArray = getValuesAsArray(dataMap, DataStore::getB);
float[] cArray = getValuesAsArray(dataMap, DataStore::getC);
Then your getValuesAsArray
will accept a Function<DataStore,Float>
parameter and execute the function :
private static float[] getValuesAsArray(Map<Integer, DataStore> dataMap, Function<DataStore,Float> func) {
int i = 0;
int nMap = dataMap.size();
float[] fArray = new float[nMap];
for (Map.Entry<Integer, DataStore> entry : dataMap.entrySet()) {
DataStore ds = entry.getValue();
fArray[i] = func.apply(ds);
i++;
}
return fArray;
}
Without using Java 8, you can define your own interface that contains a method that accepts a DataStore
instance and returns a float
. Then, instead of using Java 8 method references, you would have to pass to your getValuesAsArray
method an implementation of that interface (you could use an anonymous class instance implementing the interface) which calls one of the getX()
methods.
For example :
public interface ValueGetter
{
public float get (DataStore source);
}
float[] aArray = getValuesAsArray(dataMap, new ValueGetter() {public float get (DataStore source) {return source.getA();}});
float[] bArray = getValuesAsArray(dataMap, new ValueGetter() {public float get (DataStore source) {return source.getB();}});
float[] cArray = getValuesAsArray(dataMap, new ValueGetter() {public float get (DataStore source) {return source.getC();}});
And
private static float[] getValuesAsArray(Map<Integer, DataStore> dataMap, ValueGetter func) {
int i = 0;
int nMap = dataMap.size();
float[] fArray = new float[nMap];
for (Map.Entry<Integer, DataStore> entry : dataMap.entrySet()) {
DataStore ds = entry.getValue();
fArray[i] = func.get(ds);
i++;
}
return fArray;
}
Pass method as parameter
you can do as the following code
import java.util.Scanner;
import java.awt.geom.Point2D;
public class MyPoint {
private double x,y;
public MyPoint() {
x=0;
y=0;
}
public MyPoint(double x, double y) {
this.x = x;
this.y = y;
}
public double distance(MyPoint other) {
double distance = Math.sqrt(((this.x-other.x)*(the.x-other.x))+((this.y-other.y)*(this.y-other.y)));
return distance;
}
public static void main(String[] args){
pointOne = new Point(2.2,3.3);
pointTwo = new Point(3.3,2.2);
System.out.println(pointOne.distance(pointTwo));
}
}
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);
Java - how do I pass a method as parameter?
interface MyMethodType<T> {
T method(String name, Object[] objects);
}
private <T> T createTypeWithCorrectSearchPath(
String typeName,
Object[] objects,
MyMethodType<T> impl) {
String searchPath = getSearchPath();
String name = setSearchPathToSchema(typeName);
T ret = impl.method(name, objects);
setSearchPath(searchPath);
return ret;
}
createTypeWithCorrectSearchPath(typeName, objects, delegate()::createStruct);
The crucial bits are a) creating your own interface type, though I suppose you could use BiFunction<String, Object[]>
, b) using method references with ::
.
Related Topics
How to Override Equals Method in Java
What's the Reason I Can't Create Generic Array Types in Java
How to Format the Day of the Month to Say "11Th", "21St" or "23Rd" (Ordinal Indicator)
Fastest Way to Determine If an Integer'S Square Root Is an Integer
Are Getters and Setters Poor Design? Contradictory Advice Seen
Java.Sql.Sqlexception Parameter Index Out of Range (1 ≫ Number of Parameters, Which Is 0)
How to Concatenate Two Strings in Java
Is There a Goto Statement in Java
Program Not Accessing Method Paintcomponent() of Extended Jpanel Class
Using Threads to Make Database Requests
Sorting an Arraylist of Objects Using a Custom Sorting Order
Best Implementation For Hashcode Method For a Collection
To Prevent a Memory Leak, the Jdbc Driver Has Been Forcibly Unregistered
How Can a Java Program Get Its Own Process Id