Please explain the syntax for Java 8's lambda methods.
There are a lot of explanations out there for what lambda functions are, but I can't find a thorough explanation of the syntax, and I am finding it very difficult to learn to replicate the syntax correctly because I don't understand why they're written as they are.
Here's a common case that I run into, courtesy NetBeans:
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new MainAppJFrame();
});
}
So somehow, the following lambda expression is resolving into an anonymous Runnable object's run() method:
() -> {
// do stuff
}
The -> is the lambda syntax proper, right? And the curly braces are simply containing the anonymous method code. Are the parentheses an empty argument, because in this case we're creating a Runnable.run() method?
This is all rather unclear to me. I assume the compiler knows to instantiate an anonymous Runnable based on the type expected by the SwingUtilities.invokeLater(Runnable) method? What would happen if there were two SwingUtilities.invokeLater methods which differ only in parameter list? Obviously there aren't in this specific case, but it's possible elsewhere:
interface ExampleLambdaConsumer {
public void doSomething(Runnable r);
public void doSomething(java.lang.reflect.Method m);
}
class C implements ExampleLambdaConsumer {
// implementations for doSomething methods here
public static void main(String[] args) {
doSomething(() -> {
// lambda method body here
}
}
}
Syntax is:
arguments -> body
where arguments can be either
()
a single variable if the type of that variable can be inferred from the context
a sequence of variables, with or without types (or since Java 11, with var), in parentheses.
Examples: (x), (x, y), (int x, int y), (var x, var y) (Java 11+).
The following are invalid: (int x, y), (x, var y), (var x, int y)
and body can be either an expression or a {...} block with statements. The expression (other than a method or constructor call) is simply returned, i.e. () -> 2 is equivalent to () -> {return 2;}
In case of lambda expressions like () -> f() (the body is a method or constructor call expression):
if f() returns void, they are equivalent to () -> { f(); }
otherwise, they are equivalent to either () -> { f(); } or () -> { return f(); }). The compiler infers it from the calling context, but usually it will prefer the latter.
Therefore, if you have two methods: void handle(Supplier<T>) and void handle(Runnable), then:
handle(() -> { return f(); }) and handle(() -> x) will call the first one,
handle(() -> { f(); } will call the second one, and
handle(() -> f()):
if f() returns void or a type that is not convertible to T, then it will call the second one
if f() returns a type that is convertible to T, then it will call the first one
The compiler tries to match the type of the lambda to the context. I don't know the exact rules, but the answer to:
What would happen if there were two SwingUtilities.invokeLater methods which differ only in parameter list?
is: it depends on what would be those parameter lists. If the other invokeLater had also exactly one parameter and that parameter would be of type that is also an interface with one method of type void*(), well, then it would complain that it cannot figure out which method you mean.
Why are they written as they are? Well, I think it's because syntax in C# and Scala is almost the same (they use => rather than ->).
The syntax is
(parameter_list_here) -> { stuff_to_do; }
The curly braces can be omitted if it's a single expression. The regular parentheses around the parameter list can be omitted if it's a single parameter.
The syntax only works for all functional interfaces. The #FunctionalInterface annotation tells the compiler that you intend to write such an interface and gives a compile error if you do not meet the requirement(s) - for example it must only have 1 overrideable method.
#FunctionalInterface
interface TestInterface {
void dostuff();
}
Runnable is also declared like that. Other interfaces are not, and they cannot be used with lambda functions.
Now that we've made a new functional interface with a method that takes no parameters, how about we test the question you had about "collision" in the signatures?
public class Main {
private void test(Runnable r) {
}
private void test(TestInterface ti) {
}
public static void main(String[] args) {
test(() -> { System.out.println("test");})
}
#FunctionalInterface
interface TestInterface {
void dostuff();
}
}
Result: compile error: ambigouous call to method test.
You see, the compiler/VM(if done runtime) finds the appropriate methods and their parameter list and sees if the parameter is a functional interface and if it is it creates an anonymous implementation of that interface. Technically (in byte code) it's different from an anonymous class, but otherwise identical (you won't see Main$1.class files).
Your example code (courtesy of Netbeans) can also be replaced with
SwingUtilities.invokeLater(MainAppJFrame::new);
Btw. :)
Lambda Expressions are basically adopted in Java 8 to simplify overriding process function as anonymous functions.
They are mere shortcut to Override old java anonymous functions.
Refer following example:
Suppose you have interface A which has only one method declared like below:
interface A{
void print();
}
now with old java style we'll override this in anonymous way like below:
new A() {
#Override
public void print() {
System.out.println("in a print method");
}
};
additionally now with java 8 lambda expression we'll use it like below:
() -> System.out.println("in a print method");
Here we can pass parameters required to method before -> operator
and then overridden body after -> operator.
the only more settings that we need to achieve this is that we need to declare interface with #FunctionalInterface as below:
#FunctionalInterface
interface A{
void print();
}
Note: - A lambda expression can only be used for a "functional" interface that has only one non-default method.
The syntax is confusing.
It drives me around the twist.
If it was not for Intellij, correcting me I would get it wrong.
Compiles OK.
class Scratch {
public static void main(String[] args) {
Predicate<Integer> even = integer -> {return (integer%2 == 0);};
}
}
Compiles OK.
class Scratch {
public static void main(String[] args) {
Predicate<Integer> even = integer -> {return integer%2 == 0;};
}
}
Does NOT Compile, since it is not a statement anymore.
class Scratch {
public static void main(String[] args) {
Predicate<Integer> even = integer -> {return integer%2 == 0};
}
}
Does NOT Compile, since it is not a statement anymore and the return statement has been removed.
class Scratch {
public static void main(String[] args) {
Predicate<Integer> even = integer -> {integer%2 == 0};
}
}
Compiles OK.
class Scratch {
public static void main(String[] args) {
Predicate<Integer> even = integer -> integer%2 == 0;
}
}
So moral of the story is, if you use the brackets what is inside must
be a statement, and it must return the type expected by the Functional interface single abstract method (i.e. the only one that is not a default).
I actually wrote it more for myself than anything else, cause it was bugging me.
This question already has answers here:
Java Pass Method as Parameter
(17 answers)
Closed 8 years ago.
In Java, how can one pass a function as an argument of another function?
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.
You could use Java reflection to do this. The method would be represented as an instance of java.lang.reflect.Method.
import java.lang.reflect.Method;
public class Demo {
public static void main(String[] args) throws Exception{
Class[] parameterTypes = new Class[1];
parameterTypes[0] = String.class;
Method method1 = Demo.class.getMethod("method1", parameterTypes);
Demo demo = new Demo();
demo.method2(demo, method1, "Hello World");
}
public void method1(String message) {
System.out.println(message);
}
public void method2(Object object, Method method, String message) throws Exception {
Object[] parameters = new Object[1];
parameters[0] = message;
method.invoke(object, parameters);
}
}
Lambda Expressions
To add on to jk.'s excellent answer, you can now pass a method more easily using Lambda Expressions (in Java 8). First, some background. A functional interface is an interface that has one and only one abstract method, although it can contain any number of default methods (new in Java 8) and static methods. A lambda expression can quickly implement the abstract method, without all the unnecessary syntax needed if you don't use a lambda expression.
Without lambda expressions:
obj.aMethod(new AFunctionalInterface() {
#Override
public boolean anotherMethod(int i)
{
return i == 982
}
});
With lambda expressions:
obj.aMethod(i -> i == 982);
Here is an excerpt from the Java tutorial on Lambda Expressions:
Syntax of Lambda Expressions
A lambda expression consists of the following:
A comma-separated list of formal parameters enclosed in parentheses. The CheckPerson.test method contains one parameter, p,
which represents an instance of the Person class.Note: You
can omit the data type of the parameters in a lambda expression. In
addition, you can omit the parentheses if there is only one parameter.
For example, the following lambda expression is also valid:
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
The arrow token, ->
A body, which consists of a single expression or a statement block. This example uses the following expression:
p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
If you specify a single expression, then the Java runtime evaluates the expression and then returns its value. Alternatively,
you can use a return statement:
p -> {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
A return statement is not an expression; in a lambda expression, you must enclose statements in braces ({}). However, you do not have
to enclose a void method invocation in braces. For example, the
following is a valid lambda expression:
email -> System.out.println(email)
Note that a lambda expression looks a lot like a method declaration;
you can consider lambda expressions as anonymous methods—methods
without a name.
Here is how you can "pass a method" using a lambda expression:
Note: this uses a new standard functional interface, java.util.function.IntConsumer.
class A {
public static void methodToPass(int i) {
// do stuff
}
}
import java.util.function.IntConsumer;
class B {
public void dansMethod(int i, IntConsumer aMethod) {
/* you can now call the passed method by saying aMethod.accept(i), and it
will be the equivalent of saying A.methodToPass(i) */
}
}
class C {
B b = new B();
public C() {
b.dansMethod(100, j -> A.methodToPass(j)); //Lambda Expression here
}
}
The above example can be shortened even more using the :: operator.
public C() {
b.dansMethod(100, A::methodToPass);
}
Thanks to Java 8 you don't need to do the steps below to pass a function to a method, that's what lambdas are for, see Oracle's Lambda Expression tutorial. The rest of this post describes what we used to have to do in the bad old days in order to implement this functionality.
Typically you declare your method as taking some interface with a single method, then you pass in an object that implements that interface. An example is in commons-collections, where you have interfaces for Closure, Transformer, and Predicate, and methods that you pass implementations of those into. Guava is the new improved commons-collections, you can find equivalent interfaces there.
So for instance, commons-collections has org.apache.commons.collections.CollectionUtils, which has lots of static methods that take objects passed in, to pick one at random, there's one called exists with this signature:
static boolean exists(java.util.Collection collection, Predicate predicate)
It takes an object that implements the interface Predicate, which means it has to have a method on it that takes some Object and returns a boolean.
So I can call it like this:
CollectionUtils.exists(someCollection, new Predicate() {
public boolean evaluate(Object object) {
return ("a".equals(object.toString());
}
});
and it returns true or false depending on whether someCollection contains an object that the predicate returns true for.
Anyway, this is just an example, and commons-collections is outdated. I just forget the equivalent in Guava.
Java supports closures just fine. It just doesn't support functions, so the syntax you're used to for closures is much more awkward and bulky: you have to wrap everything up in a class with a method. For example,
public Runnable foo(final int x) {
return new Runnable() {
public void run() {
System.out.println(x);
}
};
}
Will return a Runnable object whose run() method "closes over" the x passed in, just like in any language that supports first-class functions and closures.
I used the command pattern that #jk. mentioned, adding a return type:
public interface Callable<I, O> {
public O call(I input);
}
I know this is a rather old post but I have another slightly simpler solution.
You could create another class within and make it abstract. Next make an Abstract method name it whatever you like. In the original class make a method that takes the new class as a parameter, in this method call the abstract method. It will look something like this.
public class Demo {
public Demo(/.../){
}
public void view(Action a){
a.preform();
}
/**
* The Action Class is for making the Demo
* View Custom Code
*/
public abstract class Action {
public Action(/.../){
}
abstract void preform();
}
}
Now you can do something like this to call a method from within the class.
/...
Demo d = new Demo;
Action a = new Action() {
#Override
void preform() {
//Custom Method Code Goes Here
}
};
/.../
d.view(a)
Like I said I know its old but this way I think is a little easier. Hope it helps.
Java does not (yet) support closures. But there are other languages like Scala and Groovy which run in the JVM and do support closures.
I've faced a strange(for me) behavior when I was trying to use function composition with two void methods. I've written a simple example to illustrate the problem :
public class Startup {
public static void main(String[] args) {
List<Foo> foos = new ArrayList<>();
// 1) Does not compile
foos.forEach(Startup::doSomething1.andThen(Startup::doSomething2));
Consumer<Foo> doSomething1 = Startup::doSomething1;
Consumer<Foo> doSomething2 = Startup::doSomething2;
// 2) Works as expected
foos.forEach(doSomething1.andThen(doSomething2));
}
public static void doSomething1(Foo foo) {
}
public static void doSomething2(Foo foo) {
}
public static class Foo {
}
}
When I try to compile the first solution it says "')' expected" before andThen call.
When I explicitly say this are Consumers the code is compiled and it works as expected.
Can anyone explain to my why this is happening and is there another way of doing function composition of void methods with Java 8?
Let's make this simpler:
private static boolean test(String input){
return input.equals("123");
}
Predicate<String> predicate = YourClass::test;
Function<String, Boolean> function = YourClass::test;
So a method reference is a poly expression (like generics for example), they depend on the context where they are used. So your Startup::doSomething method reference could be any #FunctionalInterface that would comply to the that method. It might look to you that it is a Consumer in this case, but it's a different story for the compiler.
This has to do with the way Java inferes, converts and detects types in lambdas. As mentioned in a comment above, the conversion to Consumer<Foo> has not taken place yet meaning that the compiler does not know that this is a Consumer so that you can chain an andThen() afterwards.
Explicitly casting this to a Consumer and using parentheses properly will let you achieve the desired effect:
List<Foo> foos = new ArrayList<>();
foos.forEach(((Consumer<Foo>) Null::doSomething).andThen(Null::doSomething2));
I guess if you fiddle around with it, you can achieve the same behavior using type witnesses but I am not 100% sure whether they can achieve the desired result.
First time I noticed this was using chained comparators which may exhibit the same behavior. Doing an online search about that will show you some more intricate details regarding how this works.
Just as the Consumer mentioned:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
And the functional interface gives us two methods:
void accept(T t)
default Consumer<T> andThen(Consumer<? super T> after)
As for andThen(...):
Returns a composed Consumer that performs, in sequence, this operation followed by the after operation.
The Functional Interface is the syntactic sugar that Java 8 provides that we can just pass in a lambda or method reference, and we can get more helpful/assistant features that we frequently need (default behaviors).
And here, we can combine several functions altogether easily using andThen
As for your case, you can just try something like this:
public class CastToFunctionalInterface {
public static void main(String... args) {
((Consumer<Integer>) CastToFunctionalInterface::consumeInteger)
.andThen(CastToFunctionalInterface::consumeAnotherInteger)
.accept(10);
}
private static void consumeInteger(Integer a) {
System.out.println("I'm an Integer: " + a);
}
private static void consumeAnotherInteger(Integer b) {
System.out.println("I'm another integer: " + b);
}
}
Output:
I'm an Integer: 10
I'm another integer: 10
I've faced a strange(for me) behavior when I was trying to use function composition with two void methods. I've written a simple example to illustrate the problem :
public class Startup {
public static void main(String[] args) {
List<Foo> foos = new ArrayList<>();
// 1) Does not compile
foos.forEach(Startup::doSomething1.andThen(Startup::doSomething2));
Consumer<Foo> doSomething1 = Startup::doSomething1;
Consumer<Foo> doSomething2 = Startup::doSomething2;
// 2) Works as expected
foos.forEach(doSomething1.andThen(doSomething2));
}
public static void doSomething1(Foo foo) {
}
public static void doSomething2(Foo foo) {
}
public static class Foo {
}
}
When I try to compile the first solution it says "')' expected" before andThen call.
When I explicitly say this are Consumers the code is compiled and it works as expected.
Can anyone explain to my why this is happening and is there another way of doing function composition of void methods with Java 8?
Let's make this simpler:
private static boolean test(String input){
return input.equals("123");
}
Predicate<String> predicate = YourClass::test;
Function<String, Boolean> function = YourClass::test;
So a method reference is a poly expression (like generics for example), they depend on the context where they are used. So your Startup::doSomething method reference could be any #FunctionalInterface that would comply to the that method. It might look to you that it is a Consumer in this case, but it's a different story for the compiler.
This has to do with the way Java inferes, converts and detects types in lambdas. As mentioned in a comment above, the conversion to Consumer<Foo> has not taken place yet meaning that the compiler does not know that this is a Consumer so that you can chain an andThen() afterwards.
Explicitly casting this to a Consumer and using parentheses properly will let you achieve the desired effect:
List<Foo> foos = new ArrayList<>();
foos.forEach(((Consumer<Foo>) Null::doSomething).andThen(Null::doSomething2));
I guess if you fiddle around with it, you can achieve the same behavior using type witnesses but I am not 100% sure whether they can achieve the desired result.
First time I noticed this was using chained comparators which may exhibit the same behavior. Doing an online search about that will show you some more intricate details regarding how this works.
Just as the Consumer mentioned:
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
And the functional interface gives us two methods:
void accept(T t)
default Consumer<T> andThen(Consumer<? super T> after)
As for andThen(...):
Returns a composed Consumer that performs, in sequence, this operation followed by the after operation.
The Functional Interface is the syntactic sugar that Java 8 provides that we can just pass in a lambda or method reference, and we can get more helpful/assistant features that we frequently need (default behaviors).
And here, we can combine several functions altogether easily using andThen
As for your case, you can just try something like this:
public class CastToFunctionalInterface {
public static void main(String... args) {
((Consumer<Integer>) CastToFunctionalInterface::consumeInteger)
.andThen(CastToFunctionalInterface::consumeAnotherInteger)
.accept(10);
}
private static void consumeInteger(Integer a) {
System.out.println("I'm an Integer: " + a);
}
private static void consumeAnotherInteger(Integer b) {
System.out.println("I'm another integer: " + b);
}
}
Output:
I'm an Integer: 10
I'm another integer: 10
I have a method that's about ten lines of code. I want to create more methods that do exactly the same thing, except for a small calculation that's going to change one line of code. This is a perfect application for passing in a function pointer to replace that one line, but Java doesn't have function pointers. What's my best alternative?
Anonymous inner class
Say you want to have a function passed in with a String param that returns an int.
First you have to define an interface with the function as its only member, if you can't reuse an existing one.
interface StringFunction {
int func(String param);
}
A method that takes the pointer would just accept StringFunction instance like so:
public void takingMethod(StringFunction sf) {
int i = sf.func("my string");
// do whatever ...
}
And would be called like so:
ref.takingMethod(new StringFunction() {
public int func(String param) {
// body
}
});
EDIT: In Java 8, you could call it with a lambda expression:
ref.takingMethod(param -> bodyExpression);
For each "function pointer", I'd create a small functor class that implements your calculation.
Define an interface that all the classes will implement, and pass instances of those objects into your larger function. This is a combination of the "command pattern", and "strategy pattern".
#sblundy's example is good.
When there is a predefined number of different calculations you can do in that one line, using an enum is a quick, yet clear way to implement a strategy pattern.
public enum Operation {
PLUS {
public double calc(double a, double b) {
return a + b;
}
},
TIMES {
public double calc(double a, double b) {
return a * b;
}
}
...
public abstract double calc(double a, double b);
}
Obviously, the strategy method declaration, as well as exactly one instance of each implementation are all defined in a single class/file.
You need to create an interface that provides the function(s) that you want to pass around. eg:
/**
* A simple interface to wrap up a function of one argument.
*
* #author rcreswick
*
*/
public interface Function1<S, T> {
/**
* Evaluates this function on it's arguments.
*
* #param a The first argument.
* #return The result.
*/
public S eval(T a);
}
Then, when you need to pass a function, you can implement that interface:
List<Integer> result = CollectionUtilities.map(list,
new Function1<Integer, Integer>() {
#Override
public Integer eval(Integer a) {
return a * a;
}
});
Finally, the map function uses the passed in Function1 as follows:
public static <K,R,S,T> Map<K, R> zipWith(Function2<R,S,T> fn,
Map<K, S> m1, Map<K, T> m2, Map<K, R> results){
Set<K> keySet = new HashSet<K>();
keySet.addAll(m1.keySet());
keySet.addAll(m2.keySet());
results.clear();
for (K key : keySet) {
results.put(key, fn.eval(m1.get(key), m2.get(key)));
}
return results;
}
You can often use Runnable instead of your own interface if you don't need to pass in parameters, or you can use various other techniques to make the param count less "fixed" but it's usually a trade-off with type safety. (Or you can override the constructor for your function object to pass in the params that way.. there are lots of approaches, and some work better in certain circumstances.)
Method references using the :: operator
You can use method references in method arguments where the method accepts a functional interface. A functional interface is any interface that contains only one abstract method. (A functional interface may contain one or more default methods or static methods.)
IntBinaryOperator is a functional interface. Its abstract method, applyAsInt, accepts two ints as its parameters and returns an int. Math.max also accepts two ints and returns an int. In this example, A.method(Math::max); makes parameter.applyAsInt send its two input values to Math.max and return the result of that Math.max.
import java.util.function.IntBinaryOperator;
class A {
static void method(IntBinaryOperator parameter) {
int i = parameter.applyAsInt(7315, 89163);
System.out.println(i);
}
}
import java.lang.Math;
class B {
public static void main(String[] args) {
A.method(Math::max);
}
}
In general, you can use:
method1(Class1::method2);
instead of:
method1((arg1, arg2) -> Class1.method2(arg1, arg2));
which is short for:
method1(new Interface1() {
int method1(int arg1, int arg2) {
return Class1.method2(arg1, agr2);
}
});
For more information, see :: (double colon) operator in Java 8 and Java Language Specification §15.13.
You can also do this (which in some RARE occasions makes sense). The issue (and it is a big issue) is that you lose all the typesafety of using a class/interface and you have to deal with the case where the method does not exist.
It does have the "benefit" that you can ignore access restrictions and call private methods (not shown in the example, but you can call methods that the compiler would normally not let you call).
Again, it is a rare case that this makes sense, but on those occasions it is a nice tool to have.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Main
{
public static void main(final String[] argv)
throws NoSuchMethodException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
{
final String methodName;
final Method method;
final Main main;
main = new Main();
if(argv.length == 0)
{
methodName = "foo";
}
else
{
methodName = "bar";
}
method = Main.class.getDeclaredMethod(methodName, int.class);
main.car(method, 42);
}
private void foo(final int x)
{
System.out.println("foo: " + x);
}
private void bar(final int x)
{
System.out.println("bar: " + x);
}
private void car(final Method method,
final int val)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
{
method.invoke(this, val);
}
}
If you have just one line which is different you could add a parameter such as a flag and a if(flag) statement which calls one line or the other.
You may also be interested to hear about work going on for Java 7 involving closures:
What’s the current state of closures in Java?
http://gafter.blogspot.com/2006/08/closures-for-java.html
http://tech.puredanger.com/java7/#closures
New Java 8 Functional Interfaces and Method References using the :: operator.
Java 8 is able to maintain method references ( MyClass::new ) with "# Functional Interface" pointers. There are no need for same method name, only same method signature required.
Example:
#FunctionalInterface
interface CallbackHandler{
public void onClick();
}
public class MyClass{
public void doClick1(){System.out.println("doClick1");;}
public void doClick2(){System.out.println("doClick2");}
public CallbackHandler mClickListener = this::doClick;
public static void main(String[] args) {
MyClass myObjectInstance = new MyClass();
CallbackHandler pointer = myObjectInstance::doClick1;
Runnable pointer2 = myObjectInstance::doClick2;
pointer.onClick();
pointer2.run();
}
}
So, what we have here?
Functional Interface - this is interface, annotated or not with #FunctionalInterface, which contains only one method declaration.
Method References - this is just special syntax, looks like this, objectInstance::methodName, nothing more nothing less.
Usage example - just an assignment operator and then interface method call.
YOU SHOULD USE FUNCTIONAL INTERFACES FOR LISTENERS ONLY AND ONLY FOR THAT!
Because all other such function pointers are really bad for code readability and for ability to understand. However, direct method references sometimes come handy, with foreach for example.
There are several predefined Functional Interfaces:
Runnable -> void run( );
Supplier<T> -> T get( );
Consumer<T> -> void accept(T);
Predicate<T> -> boolean test(T);
UnaryOperator<T> -> T apply(T);
BinaryOperator<T,U,R> -> R apply(T, U);
Function<T,R> -> R apply(T);
BiFunction<T,U,R> -> R apply(T, U);
//... and some more of it ...
Callable<V> -> V call() throws Exception;
Readable -> int read(CharBuffer) throws IOException;
AutoCloseable -> void close() throws Exception;
Iterable<T> -> Iterator<T> iterator();
Comparable<T> -> int compareTo(T);
Comparator<T> -> int compare(T,T);
For earlier Java versions you should try Guava Libraries, which has similar functionality, and syntax, as Adrian Petrescu has mentioned above.
For additional research look at Java 8 Cheatsheet
and thanks to The Guy with The Hat for the Java Language Specification §15.13 link.
#sblundy's answer is great, but anonymous inner classes have two small flaws, the primary being that they tend not to be reusable and the secondary is a bulky syntax.
The nice thing is that his pattern expands into full classes without any change in the main class (the one performing the calculations).
When you instantiate a new class you can pass parameters into that class which can act as constants in your equation--so if one of your inner classes look like this:
f(x,y)=x*y
but sometimes you need one that is:
f(x,y)=x*y*2
and maybe a third that is:
f(x,y)=x*y/2
rather than making two anonymous inner classes or adding a "passthrough" parameter, you can make a single ACTUAL class that you instantiate as:
InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f=new InnerFunc(2.0);// for the second
calculateUsing(f);
f=new InnerFunc(0.5);// for the third
calculateUsing(f);
It would simply store the constant in the class and use it in the method specified in the interface.
In fact, if KNOW that your function won't be stored/reused, you could do this:
InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f.setConstant(2.0);
calculateUsing(f);
f.setConstant(0.5);
calculateUsing(f);
But immutable classes are safer--I can't come up with a justification to make a class like this mutable.
I really only post this because I cringe whenever I hear anonymous inner class--I've seen a lot of redundant code that was "Required" because the first thing the programmer did was go anonymous when he should have used an actual class and never rethought his decision.
The Google Guava libraries, which are becoming very popular, have a generic Function and Predicate object that they have worked into many parts of their API.
One of the things I really miss when programming in Java is function callbacks. One situation where the need for these kept presenting itself was in recursively processing hierarchies where you want to perform some specific action for each item. Like walking a directory tree, or processing a data structure. The minimalist inside me hates having to define an interface and then an implementation for each specific case.
One day I found myself wondering why not? We have method pointers - the Method object. With optimizing JIT compilers, reflective invocation really doesn't carry a huge performance penalty anymore. And besides next to, say, copying a file from one location to another, the cost of the reflected method invocation pales into insignificance.
As I thought more about it, I realized that a callback in the OOP paradigm requires binding an object and a method together - enter the Callback object.
Check out my reflection based solution for Callbacks in Java. Free for any use.
Sounds like a strategy pattern to me. Check out fluffycat.com Java patterns.
oK, this thread is already old enough, so very probably my answer is not helpful for the question. But since this thread helped me to find my solution, I'll put it out here anyway.
I needed to use a variable static method with known input and known output (both double). So then, knowing the method package and name, I could work as follows:
java.lang.reflect.Method Function = Class.forName(String classPath).getMethod(String method, Class[] params);
for a function that accepts one double as a parameter.
So, in my concrete situation I initialized it with
java.lang.reflect.Method Function = Class.forName("be.qan.NN.ActivationFunctions").getMethod("sigmoid", double.class);
and invoked it later in a more complex situation with
return (java.lang.Double)this.Function.invoke(null, args);
java.lang.Object[] args = new java.lang.Object[] {activity};
someOtherFunction() + 234 + (java.lang.Double)Function.invoke(null, args);
where activity is an arbitrary double value. I am thinking of maybe doing this a bit more abstract and generalizing it, as SoftwareMonkey has done, but currently I am happy enough with the way it is. Three lines of code, no classes and interfaces necessary, that's not too bad.
To do the same thing without interfaces for an array of functions:
class NameFuncPair
{
public String name; // name each func
void f(String x) {} // stub gets overridden
public NameFuncPair(String myName) { this.name = myName; }
}
public class ArrayOfFunctions
{
public static void main(String[] args)
{
final A a = new A();
final B b = new B();
NameFuncPair[] fArray = new NameFuncPair[]
{
new NameFuncPair("A") { #Override void f(String x) { a.g(x); } },
new NameFuncPair("B") { #Override void f(String x) { b.h(x); } },
};
// Go through the whole func list and run the func named "B"
for (NameFuncPair fInstance : fArray)
{
if (fInstance.name.equals("B"))
{
fInstance.f(fInstance.name + "(some args)");
}
}
}
}
class A { void g(String args) { System.out.println(args); } }
class B { void h(String args) { System.out.println(args); } }
Check out lambdaj
http://code.google.com/p/lambdaj/
and in particular its new closure feature
http://code.google.com/p/lambdaj/wiki/Closures
and you will find a very readable way to define closure or function pointer without creating meaningless interface or use ugly inner classes
Wow, why not just create a Delegate class which is not all that hard given that I already did for java and use it to pass in parameter where T is return type. I am sorry but as a C++/C# programmer in general just learning java, I need function pointers because they are very handy. If you are familiar with any class which deals with Method Information you can do it. In java libraries that would be java.lang.reflect.method.
If you always use an interface, you always have to implement it. In eventhandling there really isn't a better way around registering/unregistering from the list of handlers but for delegates where you need to pass in functions and not the value type, making a delegate class to handle it for outclasses an interface.
None of the Java 8 answers have given a full, cohesive example, so here it comes.
Declare the method that accepts the "function pointer" as follows:
void doCalculation(Function<Integer, String> calculation, int parameter) {
final String result = calculation.apply(parameter);
}
Call it by providing the function with a lambda expression:
doCalculation((i) -> i.toString(), 2);
If anyone is struggling to pass a function that takes one set of parameters to define its behavior but another set of parameters on which to execute, like Scheme's:
(define (function scalar1 scalar2)
(lambda (x) (* x scalar1 scalar2)))
see Pass Function with Parameter-Defined Behavior in Java
Since Java8, you can use lambdas, which also have libraries in the official SE 8 API.
Usage:
You need to use a interface with only one abstract method.
Make an instance of it (you may want to use the one java SE 8 already provided) like this:
Function<InputType, OutputType> functionname = (inputvariablename) {
...
return outputinstance;
}
For more information checkout the documentation: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
Prior to Java 8, nearest substitute for function-pointer-like functionality was an anonymous class. For example:
Collections.sort(list, new Comparator<CustomClass>(){
public int compare(CustomClass a, CustomClass b)
{
// Logic to compare objects of class CustomClass which returns int as per contract.
}
});
But now in Java 8 we have a very neat alternative known as lambda expression, which can be used as:
list.sort((a, b) -> { a.isBiggerThan(b) } );
where isBiggerThan is a method in CustomClass. We can also use method references here:
list.sort(MyClass::isBiggerThan);
The open source safety-mirror project generalizes some of the above mentioned solutions into a library that adds functions, delegates and events to Java.
See the README, or this stackoverflow answer, for a cheat sheet of features.
As for functions, the library introduces a Fun interface, and some sub-interfaces that (together with generics) make up a fluent API for using methods as types.
Fun.With0Params<String> myFunctionField = " hello world "::trim;`
Fun.With2Params<Boolean, Object, Object> equals = Objects::equals;`
public void foo(Fun.With1ParamAndVoid<String> printer) throws Exception {
printer.invoke("hello world);
}
public void test(){
foo(System.out::println);
}
Notice:
that you must choose the sub-interface that matches the number of parameters in the signature you are targeting. Fx, if it has one parameter, choose Fun.With1Param.
that Generics are used to define A) the return type and B) the parameters of the signature.
Also, notice that the signature of the Method Reference passed to the call to the foo() method must match the the Fun defined by method Foo. If it do not, the compiler will emit an error.