High Order Functions in Java - java

I was wondering if there is a way to pass a function as an argument to a method. Is there anyway I can do this in Java 8? Please thoroughly explain the steps I must take in order to do so, and thank you in advance.

Yes. Look at the java.util.function package for the different types of functional interfaces you can use.
What you might want is Function<T, R> which is a signature for a function that takes in a single argument of type T and returns a value of type R. There are other interfaces for more-specific cases. For example, let's say you wanted a predicate of some kind. Then you can use Predicate<T> to describe that you want to accept a method that returns a boolean value based on some interpretation of the value of type T.
This is how a lot of the methods work on streams. For example, the forEach in Stream<T> is a method that accepts an argument of type Consumer<? super T>. This is basically a function that takes in an argument and does something with it.
As far as passing in the functions themselves, you can use method references or create an ad-hoc implementation of a functional interface through lambdas.
Here's a contrived example where I'm iterating over a map and adding all the values to a list:
List<Integer> list = new ArrayList<>();
Map<String, Integer> map = fromSomeMethod();
map.values().stream().forEach(list::add);
Here forEach accepts a consumer function of type Consumer<? super T>, which in this case is the add method from Collection<E> (which List<T> implements). Therefore, you've basically passed in a method as an argument into another method.
Here's another example where I'm using the same method, but this time I'm printing out the elements of a list:
list.stream().forEach(System.out::println);
Using this you can create your own methods that accept other methods, and it is as simple as defining an argument that is of any one of the types defined in java.util.function. For your error callback case, you could do something like this:
public void doSomething(String something, Consumer<ErrorResult> errorHandler) {
//do some stuff
if(errorHappened) {
//call the error handler with a new ErrorResult object
errorHandler.accept(new ErrorResult(...));
}
}
Then let's say you have a method that simply prints out the error result in some class
public class ConsoleErrorHandler {
public void handleError(ErrorResult result) {
System.out.println(result.getErrorMessage());
}
}
Now you can invoke doSomething with a reference to handleError from an instance of ConsoleErrorHandler:
ConsoleErrorHandler handler = new ConsoleErrorHandler();
doSomething("Something", handler::handleError);
You could even do this ad-hoc, with a lambda:
doSomething("Something", (ErrorResult result) -> {
System.out.println(result.getErrorMessage());
});
Notice that because of generics, you get compile-time type-checking so that you cannot simply pass any method that accepts a single argument into doSomething.

There's not function types in Java, so you have to use single method interfaces.
The package java.util.function defines a lot of them, but any interface with a single method can be used.
For instance:
// An interface with a single method that return
// something of type T
interface F<T> {
T doSomething();
}
class A {
// This method expect an instance of the interface F
private static String f( F<String> x ) {
// and then invokes its only method.
return x.doSomething();
}
// Test it
public static void main( String ... args ) {
//Call the method f using a
// this function literal: ()-> "hola"
System.out.println(
f( () -> "hola" )
);
}
}
The function literal:
() -> "hola"
Satisfies the interface F<T> implicitly.
In summary, you specify the type as an interface with a single method (any interface). It's even better if you use one of the existing interfaces in the java.util.function package.
I hope this helps.

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();

Generate lambda class for generic type variable using reflection

I am attempting to use Java interfaces as mixins in some high-level wrapper for type D.
interface WrapsD {
D getWrapped();
}
interface FeatureA extends WrapsD {
default ...
}
interface FeatureB extends WrapsD {
default ...
}
abstract class DWrapperFactory<T extends WrapsD> {
protected T doWrap(D d) {
return () -> d; // <- does not work
}
}
interface FeatureAB extends FeatureA, FeatureB {
}
class ProducingDWithFeatureAB extends DWrapperFactory<FeatureAB> {
protected FeatureAB doWrap(D d) {
return () -> d; // <- has to repeat this
}
}
As seen in ProducingDWithFeatureAB, doWrap has to be implemented in each sub-class even though the body is identical. (One more example of why Java generics is really broken.)
Since I already need to create concrete classes like ProducingDWithFeatureAB for other reasons and code exists in the JRE to sythesize lambda classes, it should be possible to write doWrap only once using reflection. I want to know how it can be done.
(doWrap used to be implemented using anonymous inner classes implementing the interface, which is even more biolderplate.)
This has nothing to do with generics; your generic example is just obfuscating the real issue.
Here's the core of the issue: lambda expressions need a target type that is a functional interface, and that target type must be statically known to the compiler. Your code doesn't provide that. For example, the following code would get the same error, for the same reason:
Object o = arg -> expr;
Here, Object is not a functional interface, and lambda expressions can only be used in a context whose type is a (compatible) functional interface.
The use of generics makes it more confusing (and I think you're also confusing yourself about how generics work), but ultimately this is going to be where this bottoms out.
The first thing you have to understand, is, that a method of the form
public Function<X,Y> fun() {
return arg -> expr;
}
is desugared to the equivalent of:
public Function<X,Y> fun() {
return DeclaringClass::lambda$fun$0;
}
private static Y lambda$fun$0(X arg) {
return expr;
}
whereas the types X and Y are derived from the functional signature of your target interface. While the actual instance of the functional interface is generated at runtime, you need a materialized target method to be executed, which is generated by the compiler.
You can generate instances of different interfaces for a single target method reflectively, but it still requires that all these functional interfaces have the same functional signature, e.g. mapping from X to Y, which reduces the usefulness of a dynamic solution.
In your case, where all target interfaces indeed have the same functional signature, it is possible, but I have to emphasize that the whole software design looks questionable to me.
For implementing the dynamic generation, we have to desugar the lambda expression as described above and add the captured variable d as an additional argument to the target method. Since your specific function has no arguments, it makes the captured d the sole method argument:
protected T doWrap(D d) {
Class<T> type=getActualT();
MethodHandles.Lookup l=MethodHandles.lookup();
try
{
MethodType fType = MethodType.methodType(D.class);
MethodType tType = fType.appendParameterTypes(D.class);
return type.cast(LambdaMetafactory.metafactory(l, "getWrapped",
tType.changeReturnType(type), fType,
l.findStatic(DWrapperFactory.class, "lambda$doWrap$0", tType), fType)
.getTarget().invoke(d));
}
catch(RuntimeException|Error t) { throw t; }
catch(Throwable t) { throw new IllegalStateException(t); }
}
private static D lambda$doWrap$0(D d) {
return d;
}
You have to implement the method getActualT() which ought to return the right class object, which is possible if the actual subclass of DWrapperFactory is a proper reifiable type, as you stated. Then, the method doWrap will dynamically generate a proper instance of T, invoking the desugared lambda expression’s method with the captured value of d—all assuming that the type T is indeed a functional interface, which cannot be proven at compile time.
Note that even at runtime, the LambdaMetafactory won’t check whether the invariants hold, you might get errors thrown at a later time if T isn’t a proper functional interface (and subclass of WrapsD).
Now compare to just repeating the method
protected SubtypeOfWrapsD doWrap(D d) {
return () -> d;
}
in each reifiable type that has to exist anyway…

Generic method to perform a map-reduce operation. (Java-8)

How to overload a Function with generic parameter in Java 8?
public class Test<T> {
List<T> list = new ArrayList<>();
public int sum(Function<T, Integer> function) {
return list.stream().map(function).reduce(Integer::sum).get();
}
public double sum(Function<T, Double> function) {
return list.stream().map(function).reduce(Double::sum).get();
}
}
Error: java: name clash:
sum(java.util.function.Function<T,java.lang.Double>) and
sum(java.util.function.Function<T,java.lang.Integer>) have the same erasure
Benji Weber once wrote of a way to circumvent this. What you need to do is to define custom functional interfaces that extend the types for your parameters:
public class Test<T> {
List<T> list = new ArrayList<>();
#FunctionalInterface
public interface ToIntFunction extends Function<T, Integer>{}
public int sum(ToIntegerFunction function) {
return list.stream().map(function).reduce(Integer::sum).get();
}
#FunctionalInterface
public interface ToDoubleFunction extends Function<T, Double>{}
public double sum(ToDoubleFunction function) {
return list.stream().map(function).reduce(Double::sum).get();
}
}
Another way is to use java.util.function.ToIntFunction and java.util.function.ToDoubleFunction instead:
public class Test<T> {
List<T> list = new ArrayList<>();
#FunctionalInterface
public int sum(ToIntFunction function) {
return list.stream().mapToInt(function).sum();
}
public double sum(ToDoubleFunction function) {
return list.stream().mapToDouble(function).sum();
}
}
The example you present in your question has got nothing to do with Java 8 and everything to do with how generics work in Java. Function<T, Integer> function and Function<T, Double> function will go through type-erasure when compiled and will be transformed to Function. The rule of thumb for method overloading is to have different number, type or sequence of parameters. Since both your methods will transform to take a Function argument, the compiler complains about it.
That being said, srborlongan has already provided one way to resolve the issue. The problem with that solution is that you have to keep modifying your Test class for each and every type of operation (addition,subtraction,etc) on different types (Integer,Double, etc). An alternate solution would be to use method overriding instead of method overloading :
Change the Test class a bit as follows :
public abstract class Test<I,O extends Number> {
List<I> list = new ArrayList<>();
public O performOperation(Function<I,O> function) {
return list.stream().map(function).reduce((a,b)->operation(a,b)).get();
}
public void add(I i) {
list.add(i);
}
public abstract O operation(O a,O b);
}
Create a subclass of Test that will add two Integers.
public class MapStringToIntAddtionOperation extends Test<String,Integer> {
#Override
public Integer operation(Integer a,Integer b) {
return a+b;
}
}
Client code can then use the above code as follows :
public static void main(String []args) {
Test<String,Integer> test = new MapStringToIntAddtionOperation();
test.add("1");
test.add("2");
System.out.println(test.performOperation(Integer::parseInt));
}
The advantage of using this approach is that your Test class is in line with the open-closed principle. To add a new operation such as multiplication, all you have to do is add a new subclass of Test and override the operation method to multiply two numbers. Club this with the Decorator pattern and you can even minimize the number of sub-classes that you have to create.
Note The example in this answer is indicative. There are a lot of areas of improvement (such as make Test a functional interface instead of an abstract class) which are beyond the scope of the question.
#srborlongan 's solution won't work very well :)
See a similar example - Comparator methods - comparingDouble(ToDoubleFunction), comparingInt(ToIntFunction), etc. The methods have different names, because overloading is not a good idea here.
The reason is, when you do sum(t->{...}), the compiler is unable to infer which method to call; actually it needs to resolve method overloading first, to pick one method, before inferring the type of the implicit lambda expression (based on that method's signature)
This is disappointing. In the earlier stage, Java8 had a more sophisticated inference engine, and Comparator had overloaded comparing() methods; and sum(t->{...}) would be correctly inferred too. Unfortunately, they decided to simply it :( And here we are now.
Rule of thumb for overloading methods with functional arguments: the arities of the functional interfaces must be different, unless both are 0.
// OK, different arity
m1( X->Y )
m1( (X1, X2)->Y )
// not OK, both are arity 1
m2( X->Y )
m2( A->B )
m2( t->{...} ); // fail; type of `t` cannot be inferred
// OK! both are arity 0
m3( ()->Y )
m3( ()->B )
The reason why overloading with arity 0 is OK is that the lambda expressions won't be implicit - all argument types are known (because there's no argument!), we don't need contextual information for inferring the lambda type
m3( ()-> return new Y() ); // lambda type is ()->Y
m3( ()-> return new B() ); // lambda type is ()->B

Java - Passing a method through a parameter

I'm trying to create a method that allows me to make use of what I believe is called lambdas, to execute a method over a series of connections.
Here's my code that I've come up with after some research, but it doesn't work:
performGlobalAction(()->{
// doSomething();
});
You'll also need to see the method I would assume:
private <T> void performGlobalAction(Callable<T> action) {
for(int i = 0; i < connectionList.size(); i++) {
connectionList.get(i).performAction(action);
}
}
This provides the following error:
The method performAction(Callable<T>) in the type Connection is not
applicable for the arguments (() -> {})
The goal of this method is to allow myself to construct a method "on the go" without creating a void for it.
Is this possible? It seems like I've used plenty of statements that have done this before. It seems like this is actually exactly how lambdas statements work.
The call method of the Callable interface returns a value of type T. Your lambda is simply shorthand for the call method, and likewise should return a T value.
Any interface that meets the requirements of a FunctionalInterface can be substituted by a lambda expression. Such an interface will have a single abstract method, one with no default implementation. For your question, the interface is Callable, and the abstract method is call. The lambda expression then acts as the body of that abstract method in an anonymous implementation of that interface.
Let's take as an example a method doStuff(Callable<Integer> stuff). To satisfy this interface, you could give an anonymous class:
doStuff(new Callable<Integer>(){
public Integer call(){
return 5;
}
});
Or you could use a lambda:
doStuff( () -> {
return 5;
} );
Or even more succinctly:
doStuff( () -> 5 );
If your method doesn't have a return type, perhaps Runnable would be a better fit.
See also: Lambda Expressions (Oracle) - 'Use Standard Functional Interfaces with Lambda Expressions'

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