Why can we not use default methods in lambda expressions? - java

I was reading this tutorial on Java 8 where the writer showed the code:
interface Formula {
double calculate(int a);
default double sqrt(int a) {
return Math.sqrt(a);
}
}
And then said
Default methods cannot be accessed from within lambda expressions. The
following code does not compile:
Formula formula = (a) -> sqrt( a * 100);
But he did not explain why it is not possible. I ran the code, and it gave an error,
incompatible types: Formula is not a functional interface`
So why is it not possible or what is the meaning of the error? The interface fulfills the requirement of a functional interface having one abstract method.

It's more or less a question of scope. From the JLS
Unlike code appearing in anonymous class declarations, the meaning of
names and the this and super keywords appearing in a lambda body,
along with the accessibility of referenced declarations, are the same
as in the surrounding context (except that lambda parameters introduce
new names).
In your attempted example
Formula formula = (a) -> sqrt( a * 100);
the scope does not contain a declaration for the name sqrt.
This is also hinted at in the JLS
Practically speaking, it is unusual for a lambda expression to need to
talk about itself (either to call itself recursively or to invoke its
other methods), while it is more common to want to use names to refer
to things in the enclosing class that would otherwise be shadowed
(this, toString()). If it is necessary for a lambda expression to
refer to itself (as if via this), a method reference or an anonymous
inner class should be used instead.
I think it could have been implemented. They chose not to allow it.

Lambda expressions work in a completely different way from anonymous classes in that this represents the same thing that it would in the scope surrounding the expression.
For example, this compiles
class Main {
public static void main(String[] args) {
new Main().foo();
}
void foo() {
System.out.println(this);
Runnable r = () -> {
System.out.println(this);
};
r.run();
}
}
and it prints something like
Main#f6f4d33
Main#f6f4d33
In other words this is a Main, rather than the object created by the lambda expression.
So you cannot use sqrt in your lambda expression because the type of the this reference is not Formula, or a subtype, and it does not have a sqrt method.
Formula is a functional interface though, and the code
Formula f = a -> a;
compiles and runs for me without any problem.
Although you cannot use a lambda expression for this, you can do it using an anonymous class, like this:
Formula f = new Formula() {
#Override
public double calculate(int a) {
return sqrt(a * 100);
}
};

That's not exactly true. Default methods can be used in lambda expressions.
interface Value {
int get();
default int getDouble() {
return get() * 2;
}
}
public static void main(String[] args) {
List<Value> list = Arrays.asList(
() -> 1,
() -> 2
);
int maxDoubled = list.stream()
.mapToInt(val -> val.getDouble())
.max()
.orElse(0);
System.out.println(maxDoubled);
}
prints 4 as expected and uses a default method inside a lambda expression (.mapToInt(val -> val.getDouble()))
What the author of your article tries to do here
Formula formula = (a) -> sqrt( a * 100);
is to define a Formula, which works as functional interface, directly via a lambda expression.
That works fine, in above example code, Value value = () -> 5 or with Formula as interface for example
Formula formula = (a) -> 2 * a * a + 1;
But
Formula formula = (a) -> sqrt( a * 100);
fails because it's trying to access the (this.)sqrt method but it can't.
Lambdas as per spec inherit their scope from their surroundings, meaning that this inside a lambda refers to the same thing as directly outside of it. And there is no sqrt method outside.
My personal explanation for this: Inside the lambda expression, it's not really clear to what concrete functional interface the lambda is going to be "converted". Compare
interface NotRunnable {
void notRun();
}
private final Runnable r = () -> {
System.out.println("Hello");
};
private final NotRunnable r2 = r::run;
The very same lambda expression can be "cast" to multiple types. I think of it as if a lambda doesn't have a type. It's a special typeless function that can be used for any Interface with the right parameters. But that restriction means that you can't use methods of the future type because you can't know it.

This adds little to the discussion, but I found it interesting anyways.
Another way to see the problem would be to think about it from the standpoint of a self-referencing lambda.
For example:
Formula formula = (a) -> formula.sqrt(a * 100);
It would seem that this ought to make sense, since by the time the lambda gets to be executed the formula reference must have already being initialized (i.e. there is not way to do formula.apply() until formula has been properly initialized, in whose case, from the body of the lambda, the body of apply, it should be possible to reference the same variable).
However this does not work either. Interestingly, it used to be possible at the beginning. You can see that Maurice Naftalin had it documented in his Lambda FAQ Web Site. But for some reason the support for this feature was ultimately removed.
Some of the suggestions given in other answers to this question have been already mentioned there in the very discussion in the lambda mailing list.

Default methods can be accessed only with object references, if you want to access default method you'd have an object reference of Functional Interface, in lambda expression method body you won't have so can't access it.
You are getting an error incompatible types: Formula is not a functional interface because you have not provided #FunctionalInterface annotation, if you have provided you'll get 'method undefined' error, compiler will force you to create a method in the class.
#FunctionalInterface must have only one abstract method your Interface has that but it is missing the annotation.
But static methods have no such restriction, since we can access it with out object reference like below.
#FunctionalInterface
public interface Formula {
double calculate(int a);
static double sqrt(int a) {
return Math.sqrt(a);
}
}
public class Lambda {
public static void main(String[] args) {
Formula formula = (a) -> Formula.sqrt(a);
System.out.println(formula.calculate(100));
}
}

Related

How can a parameterless method toUpperCase() implement Function.apply()? [duplicate]

This question already has answers here:
How does method reference casting work?
(3 answers)
Closed last month.
This post was edited and submitted for review last month and failed to reopen the post:
Original close reason(s) were not resolved
I'm learning Java 8 with Lambda, Streams, and method reference. Regarding the example below,
Optional<String> s = Optional.of("test");
System.out.println(s.map(String::toUpperCase).get());
I don't understand how is it possible to use String::toUpperCase as an input for this map() method.
This is the method implementation:
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
So it requires a function interface, and it has this apply() method: R apply(T t); This method has an input argument.
And toUpperCase() method doesn't have any argument:
public String toUpperCase() {
return toUpperCase(Locale.getDefault());
}
If the abstract method apply(T t) has one argument, then the implemented method should have one argument of the same type. How can parameterless method toUpperCase() implement the apply(T t) method from a function interface?
I try to recreate the same conditions:
I create a functional interface:
public interface Interf {
String m1(String value);
}
Then I create a class with the method reference for m1():
public class Impl {
public String value;
public String toUpp() {
return value.toUpperCase();
}
}
And here is a class for test:
public class Test {
public static void main(String[] args) {
Interf i = String::toUpperCase;
System.out.println(i.m1("hey"));
Interf i1 = Impl::toUpp;
System.out.println(i.m1("hello"));
}
}
There isn't any issue at this statement: Interf i = String::toUpperCase; but there is a compilation error on this line: Interf i1 = Impl::toUpp;. It says:
Non-static method cannot be referenced from a static context
But toUpperCase() is also a non-static method. And even if I make the toUpp() static, it is still not working, it is working only if I add a String argument as an input argument for toUpp(). But then why is it working for String::toUpperCase?
TL;DR
Parameters that a Method reference is expected to consume according to the contract imposed by a Functional interface it implements are NOT necessarily the same as parameters of the method used in the Method reference.
This answer is a journey from this common misconception towards understanding all syntactical flavors of Method references.
Let's take tiny baby steps to dispel misunderstanding, starting from the definition of the Method reference.
What is Method reference
Here is the definition of the Method reference according to the Java Language Specification §15.13. Method Reference Expressions
A method reference expression is used to refer to the invocation of a
method without actually performing the invocation. Certain forms of
method reference expression also allow class instance creation (§15.9)
or array creation (§15.10) to be treated as if it were a method
invocation.
emphasis added
So, a Method reference is a mean of referring the method-invocation without invoking a method. Or in other words, it's a way of describing a certain behavior by delegating to the existing functionality.
Let's take a small detour and have a look at the sibling of a Method reference, a Lambda expression.
Lambda expressions are also a way to describe behavior (without executing it), and both lambdas and Method references should conform to a Functional interface. Let's declare some lambdas.
Consider, we have a domain class Foo and utility class FooUtils.
public class FooUtils {
public static Foo doSomethingWithFoo(Foo foo) {
// do something
return new Foo();
}
}
And we need to define a function of type UnaryOperator<Foo>, let's start with writing a lambda expression:
UnaryOperator<Foo> fooChanger = foo -> FooUtils.doSomethingWithFoo(foo);
Lambda receives an instance of Foo as an argument and feeds it into the existing utility method. Quite simple, right? Nothing special happens inside the lambda's body, and since have defined the type as UnaryOperator<Foo> the lambda should expect Foo. Everything is absolutely predictable, isn't it? Now the question is: can we alternate that?
Sure, we can!
UnaryOperator<Foo> fooChanger = FooUtils::doSomethingWithFoo;
That's where a Method reference comes to the rescue. It provides a shortened syntax by:
1. Dropping the lambda's arguments (they are still there, we're simply not displaying them because we know what they are).
2. Removing the parentheses after the method name. Again the method declaration is known (and let's assume that there are no ambiguities), and we are not performing any prior transformation with arguments, and we are not using any additional arguments apart from those that should come according to the contract of the Functional interface. Only in this case everything is predictable and can a method reference.
Key takeaways:
you may think of method references as if they are shortened lambdas.
the arguments of the method reference are the same the equivalent lambda receives because they are implementations to the same interface. These parameters are still there implicitly, just dropped for the purpose of conciseness. And more importantly, parameters that a method reference consumes should not be confused with parameters expected method it refers to. In other word the first parameters an input of the method reference (and they are compliant with the contract defined by the interface) and the latter related to what happens inside the reference, and have no connection to the first ones.
More examples
Let's examine a few more examples. Let's say we have a simple object representing a coin with a single property isHeads describing which side the coin is showing (i.e. heads or tails).
public static class Coin {
public static final Random RAND = new Random();
private final boolean isHeads;
public Coin() {
this.isHeads = RAND.nextBoolean();
}
private Coin(boolean isHeads) {
this.isHeads = isHeads;
}
public Coin reverse() {
return new Coin(!isHeads);
}
public boolean isHeads() {
return isHeads;
}
}
Let's generate a coin. For that we can use implement of Supplier which very generous, supplier doesn't receive arguments, it produces a value. Let's definable both a lambda and a reference
Supplier<Coin> coinProducer = () -> new Coin(); // no argument required according to the contract of Supplier
Supplier<Coin> coinProducer1 = Coin::new; // Supplier expressed as a reference to no-args constructor
Both don't receive any argument (as per contract of the Supplier), both refer to the no-arguments constructor.
Now let's consider the predicates determining if the coin shows heads implemented via a lambda and a method reference:
Predicate<Coin> isHeads = coin -> coin.isHeads();
Predicate<Coin> isHeads1 = Coin::isHeads;
Again, both the lambda and the method reference are compliant with the Predicate's contract and both receive an instance of Coin as an argument (it can't be otherwise, simply concise syntax of the method reference doesn't show that).
So far, so good? Let's move further and try another way to obtain a Coin, let's define a Function:
Function<Boolean, Coin> booleanToCoin = value -> new Coin(value);
Function<Boolean, Coin> booleanToCoin1 = Coin::new;
Now both the lambda and the reference are consuming a boolean value and making use of the parameterized constructor. Did not notice that method reference describing Supplier<Coin> and Function<Boolean, Coin> looks identical.
Reminder: both Lambda expressions and Method references have no type by itself. They are so-called poly-expressions, which means their type should be inferred by the compiler based on the context in which they appear. Both the lambda and the reference should conform to a Functional interface, and the interface they implement dictates who they are and what they are doing.
In all examples described earlier, arguments of consumed by a method reference appeared to be the same as the ones expected by the referenced method, but it's not mandatory for them to be the identical. It's time to examine a couple or examples where it not the case to dispel the illusions.
Let's consider a UnaryOperator reversing a coin:
UnaryOperator<Coin> coinFlipper = coin -> coin.reverse(); // UnaryOperator requires one argument
UnaryOperator<Coin> coinFlipper1 = Coin::reverse; // UnaryOperator still requires one argument expressed as a reference to no arg method
All implementations of the UnaryOperator receive a Coin instance as an argument, and another coin is being produced as a result of the invocation of reverse(). The fact that reverse is parameterless is not an issue, because we concerned about what it produces, and not what it consumes.
Let's try to define a tougher method reference. To begin with, introduce in the Coin class a new instance method called xor(), which is immensely useful for XOR-ing two coins:
public Coin xor(Coin other) {
return new Coin(isHeads ^ other.isHeads);
}
Now when two object come into play we have more possibilities, let's start with the simplest case one by defining a UnariOperator:
final Coin baseCoin = new Coin();
UnaryOperator<Coin> xorAgainstBase = coin -> baseCoin.xor(coin);
UnaryOperator<Coin> xorAgainstBase1 = baseCoin::xor;
In the above example an instance of Coin defined outside the function is used to perform the transformation via the instance-method.
A little bit more complicated case would be a BinaryOperator for XOR-ing a couple of coins might look like this:
BinaryOperator<Coin> xor = (coin1, coin2) -> coin1.xor(coin2);
BinaryOperator<Coin> xor1 = Coin::xor;
Now we have two arguments coming as an input and a Coin instance should be produce as an output as per BinaryOperators contract.
The interesting thing is the first argument serves as an instance on which the method xor() would be invoked, and the second is passed to the method (note that xor() expect only one argument).
You might ask what would happen if there would be another method for XOR-ing coins. A static method expecting two arguments:
public static Coin xor(Coin coin1, Coin coin2) {
return new Coin(coin1.isHeads ^ coin2.isHeads);
}
Then the compiler would fail to resolve the method reference, because here we have more the one potentially applicable method and none of them can be considered to be more specific than the other since the types of arguments are the same. That would cause a compilation error. But if we would have either of them (not both together), reference Coin::xor would work fine.
Types of Method references
Basically, the examples that we have walked through covered all the types of method references. Now, let's enumerate them.
The official tutorial provided by Oracle re are four kinds of method references:
Reference to a Static method
Class::staticMethod
Example Coin::xor which refers to the static method xor(Coin coin1, Coin coin2).
Examples with standard JDK-classes:
BinaryOperator<Integer> sum = Integer::sum; // (i1, i2) -> Integer.sum(i1, i2)
BiFunction<CharSequence, Iterable<CharSequence>, String> iterableToString
= String::join; // (delimiter, strings) -> String.join(delimiter, strings)
Reference to an instance method of a particular object
instance::instanceMethod
The example illustrating this case would the usage of the instance method xor(Coin other) with a coin defined outside the function, which is internaly used to invoke xor() on it passing the function-argument into the method.
final Coin baseCoin = new Coin();
UnaryOperator<Coin> xorAgainstBase1 = baseCoin::xor; // same as coin -> baseCoin.xor(coin)
Examples with standard JDK-classes:
Set<Foo> fooSet = // initialing the Set
Predicate<Foo> isPresentInFooSet = fooSet::contains;
Reference to an Instance Method of an Arbitrary Object of a Particular Type
Class::methodName
In this case method refernce operates on an instance that comes as an argument (we would have reference to it only it we would use a lambda), therefore containing type, which can be tha actual type or one the super types, is used to refer to this instance.
An example would a Predicate checking if the coin shows heads Coin::isHeads.
Examples with standard JDK-classes:
Function<List<String>, Stream<String>> toStream = Collection::stream;
List<List<String>> lists = List.of(List.of("a", "b", "c"), List.of("x", "y", "z"));
List<String> strings1 = lists.stream()
.flatMap(toStream)
.toList();
// A slightly more complicate example taken from the linked tutorial
// Equivalent lambda: (a, b) -> a.compareToIgnoreCase(b)
String[] stringArray = { "Barbara", "James", "Mary" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
Reference to a Constructor
Class::new
We have cove this case already with the following examples:
Supplier<Coin> refering to no args-constracor implemented as Coin::new;
Function<Boolean, Coin> which makes use of the single-arg constructor by passing incoming boolean value also expressed as Coin::new.
How can toUpperCase() method implement apply(T t) method from Function
interface?
The method reference String::toUpperCase has unbound receiver.
Java 8: Difference between method reference Bound Receiver and UnBound Receiver
Then the argument T t would be the receiver
In your example
public <U, T> Optional<U> map(Function<? super T, ? extends U> mapper) {
...
return Optional.ofNullable(mapper.apply(value));
}
by calling map(String::toUpperCase)
If value, let's say equal to "Example String", would be the receiver so mapper.apply("Example String"); would be equivalent to "Example String".toUpperCase();

Java 8 and lambda calculus equivalent

Does anybody have any idea on how to write the basic expressions of (untyped) lambda calculus in java? i.e.
identity (λx.x),
self application (λx.x x) and
function application (λx.λarg.x arg)
Java is not untyped, so I guess any solution will have to accomodate types.
But I only found the following, cumbersume to read, solutions:
static<T> Function<T,T> identity() {
return x->x;
}
static<T> Function<? extends Function<? super Function,T>,T> self() {
return x->x.apply(x);
}
static <B,C> Function<? extends Function<B,C>, Function<B,C>> apply() {
return x -> arg -> x.apply(arg);
}
and I am not even sure they are correct(!). Can anybody propose a better alternative?
Edit: Note, that I am trying to apply the basic notions of lambda calculus with as little as possible of syntactic sugar or ready-made functions. E.g. I know there is identity(), BiFunction etc. I am trying to implement the above with only the basic lambda constructs available, and that means basically only function application
Your solutions for identity and application are correct. If wouldn't define them as functions however, I find x->x and Function::apply as readable as identity() and apply(), so I would simply use them directly.
As for self-application, well, as you note Java is typed, and also in typed lambda calculus self-application is impossible (at least in all typed lambda calculi I know). You can produce something by using raw types (like you did), but then you essentially throw away the part of the type system.
But also, why do you need all this?
What your looking for is this type(translated from table 19 of cardelli's type systems paper).
interface Untyped {
Untyped call(Untyped x);
}
This type cleanly embeds the untyped lambda calculus's terms.
static Untyped identity = x -> x;
static Untyped self = x -> x.call(x);
static Untyped apply = f -> x -> f.call(x);
I don't use Java much, but it has included lambda expressions recently. Basic way to implement is to have a functional interface (interface having only one method).
The lambda will then be a type of this interface.
interface Apply
{
String ApplyArg(int x);
}
public static void main(String args[])
{
Apply isEven = (n) -> (n%2) == 0;
//output true
System.out.println(isEven.ApplyArg(4));
}
You can use generic type interface to make it more universal.
If you want to send lambda as arguments (thus higher order functions) then your interface method will accept another interface.
interface Increment {
Int myFunction(Int x);
}
public static Int AnotherFunc(Increment test, Int y){
return test.myFunction(y);
}
public static void main (String args[]) {
Increment inc = (z) -> z++;
AnotherFunc(inc, 1); //output 2
}

lambda expression vs static method

I had a question about reusability of lambda expression without code duplication. For example if I have a helper method I can easily code it as a static method and can refer to it from other classes without code duplication. How would this work in lambda expression ?
Example: I have the following static method written
public class MyUtil {
public static int doubleMe(int x) {
return x * 2;
}
}
I can reuse the same method without code duplication in multiple places across the project
public class A {
public void someOtherCalculation() {
MyUtil.doubleMe(5);
}
}
public class B {
public void myCalculation() {
MyUtil.doubleMe(3);
}
}
How would it work when it comes to a lambda function, write the function once and use the same at multiple class.
Function<Integer, Integer> doubleFunction = x -> x * 2;
In my example, where would I write the above lambda function and how would I reuse the same in class A and B ?
Where would I write the above lambda function
Since your function does not reference any fields, it is appropriate to put it in a static final field:
class Utility {
public static final Function<Integer,Integer> doubleFunction = x -> x * 2;
}
how would I reuse the same in class A and B?
You would refer to it as Utility.doubleFunction, and pass it in the context where it is required:
callMethodWithLambda(Utility.doubleFunction);
Note that method references let you define a function, and use it as if it were lambda:
class Utility {
public static Integer doubleFunction(Integer x) {
return x*2;
}
}
...
callMethodWithLambda(Utility::doubleFunction);
This approach is very flexible, because it lets you reuse the same code in multiple contexts as you find appropriate.
Really, anonymous functions are for cases where code reuse isn't necessary.
Dumb example, but say you're using map to add two to every number in a list. If this is a common action that you may need all over the place, a static function that adds two to a number makes more sense than writing the same lambda everywhere.
If, however you have a single function that adds two to a list, it makes more sense to define the "add two" function locally as a lambda so you dont plug up your class with code that isn't needed anywhere else.
When writing Clojure, which makes extensive use of higher-order functions, it's pretty common for me to create local anonymous functions that tidy up the code in the "full" function that I'm writing. The vast majority of these anonymous functions would be non-sensical in the "global" scope (or class-scope); especially since they usually have closures over local variables, so they couldn't be global anyways.
With lambda expressions, you don't need to worry about reusability (in fact, most of the lambdas are not being re-used at all). If you want a Function pointer to point to this method the you can declare one like below:
Function<Integer, Integer> doubleFunction = MyUtil::doubleMe;
And pass it to any method or stream to apply/map, e.g.:
public static void consume(Function<Integer, Integer> consumer, int value){
System.out.println(consumer.apply(value));
}
public static void main(String[] args) throws Exception{
Function<Integer, Integer> doubleFunction = MyUtil::doubleMe;
consume(doubleFunction, 5);
}
Different from other answers. I'd like to answer your question in TDD way.
IF your doubleMe is so simple as you have wrote, that is clrealy you should stop abusing method expression reference and just call it directly as a common method invocation.
IF your doubleMe is so complicated that you want to test doubleMe independent , you need to make implicit dependencies explicity by dependency injection to testing whether they can working together by their cummunication protocols. But java can't refer a method dierctly except you using reflection api Method/using a anonymous class that implements SAM interface which delegates request to a method before in jdk-8. What the happy thing is you can refer a method expression reference to a functional interface in jdk-8. so you can make implicit dependencies explicit by using functional interface, then I would like write some communication protocol test as below:
#Test
void applyingMultiplicationWhenCalculating???(){
IntUnaryOperator multiplication = mock(IntUnaryOperator.class);
B it = new B(multiplication);
it.myCalculation();
verify(multiplication).applyAsInt(3);
}
AND then your classes like as B applied dependency injection is more like as below:
public class B {
IntUnaryOperator multiplication;
public B(IntUnaryOperator multiplication){
this.multiplication = multiplication;
}
public void myCalculation() {
multiplication.applyAsInt(3);
}
}
THEN you can reuse a method by refer a method expression reference to a functional interface as below:
A a = new A(MyUtil::doubleMe);
B b = new B(MyUtil::doubleMe);
You can do something like below.
class Fn {
public static final Function<Integer, Integer> X2TIMES = x -> x *2;
}
class Test {
public static void main (String[] args) {
System.out.println(Fn.X2TIMES.apply(5));
}
}

Lambda expression gives "invalid tokens" syntax error in Java

I just started to learn about Lambda Expression and I did something like this:
public class LambdaTest {
public static void main(String[] args) {
int num = returnNumber((num) -> { return 4 });
}
public static int returnNumber(int num) {
return num;
}
}
But it gives me an error: "invalid tokens". Here is an image:
Can someone please explain me what's wrong? It's just a test.
I have Java 1.8 supported in my Eclipse installation (Luna 4.4).
There are a few restrictions on what can be done in the body of the lambda, most of which are pretty intuitive—a lambda body can’t “break” or “continue” out of the lambda, and if the lambda returns a value, every code path must return a value or throw an exception, and so on. These are much the same rules as for a standard Java method, so they shouldn’t be too surprising.
Reference : http://www.oracle.com/technetwork/articles/java/architect-lambdas-part1-2080972.html
The method's body has the effect of evaluating the lambda body, if it
is an expression, or of executing the lambda body, if it is a block;
if a result is expected, it is returned from the method.
If the function type's result is void, the lambda body is either a
statement expression or a void-compatible block.
Reference : http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.4
The syntax error is pretty straight-forward. It says that there is a ; missing after a statement and that’s in no ways other than with statements outside lambda expressions. If you write (num) -> { return 4 }, there must be a semicolon after return 4 as it would have to be at every place where you can write return 4 (I’m astounded why nobody else was capable of telling you that).
You can write a lambda expression returning an int in two ways, either like (num) -> { return 4; } or, much simpler, as num -> 4 (here, without semicolon).
But, of course, you can’t call returnNumber(int num) with a lambda expression as parameter as it expects an int and not a functional interface. Your compiler will tell you that once you fixed the structural syntax error of the missing semicolon.
Lambdas are just implementations for method of functional interface (interfaces with one abstract methods), but in case of
returnNumber(int num)
lambdas can't be used because:
int is not an functional interface
so lambdas can't be used to supply implementation of its only abstract method (since primitive types are primitive - they have no methods).
Before lambdas to execute method like
method(SomeInterface si){...}
you would need to either create separate class which would implement this interface
class MyClass implements SomeInterface{
void method(Type1 arg1, Type2 arg2){
//body
}
}
...
MyClass mc = new MyClass();
method(md);
or add its implementation on fly by creating anonymous class
method(new SomeInterface{
void method(Type1 arg1, Type2 arg2){
//body
}
});
Lambdas can shorten this process by skipping this idiom and letting you focus only on arguments types, and implementation.
So instead of
new SomeInterface{
void method(Type1 arg1, Type2 arg2){
//body
}
}
you can simply write
(Type1 arg1, Type2 arg2) -> { body } // you can actually shorten it even farther
// but that is not important now

What's the nearest substitute for a function pointer in Java?

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.

Categories

Resources