Java Pass Method as Parameter

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



Leave a reply



Submit