How to pass a method as a parameter using lambdas is discussed here:
Java Pass Method as Parameter
In other languages, namely C++, it is possible to bind a function to it's parameters using Lambdas - discussed here:
Bind Vs Lambda?
Is it possible, in Java, to bind a method using lambdas?
If so, how would you accomplish this?
Edit >>>>
An example, by request, of what I am generally trying to do:
Be warned, there is pseudo code here.
public class DataView {
private static ArrayList<Float> rectData = new ArrayList<Float>();
private static ArrayList<Float> textData = new ArrayList<Float>();
DataView(){
//Pseudo Code:
boundFunction mybind = boundFunction(functionA, 5, 10);
boundFunction mybind2 = boundFunction(functionB, 10, 12);
iter(mybind);
iter(mybind2);
}
//Method with pseudo parameter
private void iter(functionSignature){
for(Float i : textData){
//Pseudo call to pseudo parameter
functionSignature();
}
}
private void functionA(int a, int b){
//dostuff
}
private void functionB(int a, int b){
//do other stuff
}
}
Bare in mind, I'm not looking for 'another way to accomplish this functionality' - this example is to illustrate a general way in which I would like to use functions as parameters, and to bind parameters to those functions.
Edit>>>
Attempt using anonymous classes:
public class DataView {
private class Bound{
public void run(){}
}
private static ArrayList<Float> rectData = new ArrayList<Float>();
private static ArrayList<Float> textData = new ArrayList<Float>();
DataView(){
Bound mybind = new Bound(){
public void run(){
functionA(5,10);
}
};
Bound mybind2 = new Bound(){
public void run(){
functionB(5,10);
}
};
iter(mybind);
iter(mybind2);
}
private void iter(Bound function){
for(Float i : textData){
function.run();
}
}
private void functionA(int a, int b){
//dostuff
}
private void functionB(int a, int b){
//do other stuff
}
}
As said in other answers, Java requires an actual functional interface type to represent a function. This also applies to a bind operation which requires even two of such interfaces, one to represent the unbound function and one for the bound function:
public class DataView {
interface NoArgFunction {
void func();
}
interface TwoIntFunction {
void func(int a, int b);
}
static NoArgFunction bind(TwoIntFunction f, int first, int second) {
return () -> f.func(first, second);
}
private static ArrayList<Float> rectData = new ArrayList<Float>();
private static ArrayList<Float> textData = new ArrayList<Float>();
DataView(){
NoArgFunction mybind = bind(this::functionA, 5, 10);
NoArgFunction mybind2 = bind(this::functionB, 10, 12);
iter(mybind);
iter(mybind2);
}
private void iter(NoArgFunction noArg){
for(Float i : textData){
noArg.func();
}
}
private void functionA(int a, int b){
//dostuff
}
private void functionB(int a, int b){
//do other stuff
}
}
As a fun fact, on the bytecode level, there is a capability to combine a method with arguments without the intermediate step, which is exactly what is being used by the lambda expression () -> f.func(first, second)
, which gets compiled into a synthetic method holding the lambda body and having two parameters for first
and second
which will be used at runtime to construct the NoArgFunction
instance binding the current values of first
and second
.
But you can’t use this in Java source code. The only supported binding for existing methods is the one seen at the method references this::functionA
and this::functionB
, both binding the current this
instance to the methods functionA
and functionB
. Well, using a lambda expression like
NoArgFunction mybind = () -> functionA(5, 10);
in the first place without a bind
method does short-cut the process…
So the bottom line is that there’s not much sense in trying to fight against the language trying to model a feature that isn’t intrinsically supported. Using a lambda expression instead of binding, together with a target type predefined for this purpose makes the code much simpler:
public class DataView {
private static ArrayList<Float> rectData = new ArrayList<Float>();
private static ArrayList<Float> textData = new ArrayList<Float>();
DataView(){
iter(x -> functionA(5, 10));
iter(x -> functionB(10, 12));
}
private void iter(Consumer<Float> function){
textData.forEach(function);
}
private void functionA(int a, int b){
//dostuff
}
private void functionB(int a, int b){
//do other stuff
}
}