Suppose a simple example of functors in C++:
class Test2 {
private:
double a;
public:
Test2 (double a_) : a(a_){}
double operator () () {return 10*a;}
};
template <typename Function>
double test ( Function function ) {return function();}
int main(int argc, char* argv[]) {
double a = test( Test2(5) );
return 0;
}
Is there any way to implement this construction in Java (for example using the interface Functor)? Could you give me a short example? Thanks for your help.
In Java 8, you can use the DoubleSupplier interface to get a double value from an object:
public class Test implements DoubleSupplier {
private double a;
public Test(double a) { this.a = a; }
public double getAsDouble() { return 10 * a; }
public static double test(DoubleSupplier ds) {
return ds.getAsDouble();
}
public static void main(String[] args) {
double a = test(new Test(5));
}
}
If you aren't using Java 8, then you could just make your own interface to implement from:
public interface MyDoubleSupplier {
double getAsDouble();
}
There's no exact equivalent in Java, as there's nothing like overloading the meaning of () as you can do in C++.
Since Java 8 you can program in a functional style in Java, and there are a number of standard functional interfaces in the package java.util.function.
You could do something like this:
import java.util.function.DoubleSupplier;
public double test(DoubleSupplier supplier) {
return supplier.getAsDouble();
}
public DoubleSupplier newSupplier(double a) {
return () -> 10 * a;
}
// use it:
double a = test(newSupplier(5));
You aren't going to get exactly the same thing in Java, but the principle of what you're doing should be the same.
If you want a functor in Java that can be called like functor_obj(), that's not possible. Java doesn't allow operator overloading*, so that kind of syntax simply isn't possible.
However, Java 8 introduced the concept of "Functional Interfaces", which are defined as any Interface which has exactly one [abstract**] function. Any time you're working with a Functional Interface, it's instantiation can be replaced with a lambda expression.
Runnable run = () -> {System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)");};
Thread thread = new Thread(run);
//Also Equivalent to the two above lines:
//Thread thread = new Thread(() -> {System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)");});
thread.start();
thread.join();
If you wanted to invoke this particular functor, you'd simply invoke it the same you would any other object that implemented an Interface:
run.run();
Because what Java Lambda expressions do is hide the implementation. The following code:
Runnable run = () -> {System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)");};
Does the same thing as the Java 7 equivalent code:
Runnable run = new Runnable() {
public void run() {
System.out.println("Hello World (FROM THE SECOND DIMEN—I mean THREAD)");
}
};
So for your example, you'd probably write something like this:
public static double test(Supplier<Double> f) {//imported from java.util.function
return f.get();
}
Which could then be invoked like this:
double a = test(() -> 25);
Which is equivalent to the code you wrote in your original main function. And if you need to store the functor for future use, you'd write it like this:
Supplier<Double> sup = () -> 25;
double a = test(sup);
/*sup can now be stored somewhere or passed to a different function.*/
* - I mean, Java DOES have operator overloading for String objects to allow the use of + to concatenate objects, but that's pretty much the only situation where it's used.
** - Java 8 also introduced "Default" methods to interfaces, which allows interfaces to have implemented methods. That might seem weird, until you realize it lets you write stuff like public default void sort() which can be added to java.util.List<T> to allow for all lists, which have accessors and removal operations, to be sorted using a common, generic algorithm.
Related
I'm trying to generalise some code by iterating over all constants of an enum to receive the same specific argument from each one.
Specifically I have an enum P with some constants A,B,C.
Each of these constants is itself an enum and implements an interface I that defines a function f.
P.values() gives me an array P[] A = {A,B,C}, however I can't call A[i].f() since A[i] is of course of type P which doesn't implement I.
Now in my understanding a function can return an interface, but I can not instantiate it and therefore can't cast to it.
Should I overwrite values() for P to return I[]? If so, how would I do that since I can't cast to I? Or is there another solution?
I am working in eclipse but assuming that it's complaints are indicative of a true mistake, not just eclipse not recognising types.
Since I'm somewhat new to Java I would also appreciate any links to resources that explain the underlying rules of type matching/checking.
This seems to do what you describe - perhaps I have misunderstood your question though. If so please explain further.
interface I {
void f ();
}
enum P implements I{
A,
B,
C {
// Demonstrate enum-specific implementation.
#Override
public void f () {
System.out.println("SEEEEEE!");
}
};
// By default `f` prints the name of the enum.
#Override
public void f () {
System.out.println(name());
}
}
public void test() throws Exception {
for ( I i : P.values()) {
i.f();
}
}
I'm learning how to use lambda expressions now, and I've seen some tutorials with a simple example:
(int x) -> x + 5;
But my compiler is showing this error:
Syntax error, insert "AssignmentOperator Expression" to complete Expression
Am I forgetting something?
Lambda expressions always have to be assigned to a reference type of Functional Interafces (also called single abstract method interfaces). Infact, they provide shortcut to the verbose anonymous class (with single method) implementations.
So, in simple words, Lambda expression = abstract method implementation (of the functional interface).
For example, your expression can be assigned to the below Functional Interface:
public interface MyInterface {//define Functional Interafce (SAM)
public int someMethod(int a);
}
public class Test {
public static void main(String[] args) {
MyInterface myInterface = (int a) -> a +5;//assign the expression to SAM
int output = myInterface.someMethod(20)); //returns 25
}
}
Lambdas are expressions that cannot be used as statements. From JLS8 §15.27:
It is a compile-time error if a lambda expression occurs in a program in someplace other than an assignment context (§5.2), an invocation context (§5.3), or a casting context (§5.5).
Consider this example:
// functional interface
interface Operator
{
int apply(int a, int b);
}
// method that expects instance of the interface
int calculate(int a, int b, Operator op)
{
return op.apply(a, b);
}
// lambda expression
Operator plus = (a, b) -> a + b;
// method call
calculate(40, 2, plus);
The issue is, as pointed out above, you are not doing anything with the lambda. This means that:
the compiler does not know which functional interface (e.g. java.util.function.Function) to infer as the type for your lambda.
Your line of code is "not a statement" (another error message often emitted by the compiler). This is similar to something like this:
"Hello";
Which is not valid Java.
A lambda expression cannot stand alone in Java, it need to be associated to a functional interface.
public interface myinterface
{
int mymethod(int a,int b);
}
public static void main(String[] args)
{
myinterface my = ( a,b ) -> {
int mul = a*4;
int add = a+b;
return add; };
}
Note: This is the first and last time you will see implemention of interface without keyword "Implements".
Play Around: try adding a new dummy method to your interface myinterface and you will see that your code will fail to compile, thus indicating that reference has to be only made from Functional interface not from general interfaces.
public interface myinterface
{
int mymethod(int a,int b);
int newmethod(String j);
}
public static void main(String[] args) {
myinterface my = ( a,b ) -> {
int mul = a*4;
int add = a+b;
return add;
};
Compilation Error: The target type of this expression must be a
functional interface
I wrote a sort function and class in Java:
public class MiscellaneousUtilities {
/**
* Changes a list of "First Last" to "Last, First" and "First Middle Last" to "Last, First Middle", etc.
*/
public static Function<String, String> ToLastFirstFunction = new Function<String, String>() {
#Override
public String apply(String nm) {
String[] nmarr = nm.split(" ");
int last = nmarr.length - 1;
String res = nmarr[last];
if (last > 0) {
res += ",";
}
for (int i = 0; i < last; i++) {
res += " " + nmarr[i];
}
return res;
};
};
}
When I want to use it I can't just say MiscellaneousFunctions.ToFirstLastFunction()
I have to do a new MiscellaneousFunctions().ToFirstLastFunction;
I tried putting static in front of the class declaration but it allows only public, final and abstract. Looking at the Math class if I want to use Math.min() I don't have to do a new Math().min(). Math is also defined as a class that does not have static in front of it, and min() does as does ToFirstLastFunction, so I don't understand the difference.
That's because you have to call that function with an apply like this:
MiscellaneousFunctions.ToFirstLastFunction.apply("yourstring");
You can add an other static function as a shorthand though:
public static String toFirstLast(String str) {
return ToLastFirstFunction.apply(str);
}
The main difference between Math.min and your solution that Math.min is a regular static method while you have a Function object and those can be called with apply.
Math.min() is a a method not a function, declared like this in Math.class:
public int min(int a, int b) {
...
}
... and it is methods like this that you can invoke directly as in int x = Math.min(3,2).
You have created a public static class variable called ToLastFirstFunction -- that's not something you can call like a method. But you can do things with it using the methods in the java.util.function.Function interface -- the simplest being apply():
String out = MiscellaneousFunctions.toFirstLastFunction.apply("John Doe");
(I changed the capitalisation of your identifier -- find out about Java capitalisation conventions)
It is not the case that you can call your public static Function<...> using new MiscellaneousFunctions().toFirstLastFunction("John Doe") -- I'm not sure why you thought it was so.
You can do new MiscellanousFunctions().toFirstLastFunction.apply("John Doe") -- but your compiler should warn you about accessing a static variable via an instance. MiscellanousFunctions.toFirstLastFunction.apply() is the right way.
So the short answer to your question is: if you want to invoke it that way, write it as a method.
But if that's the case, why would you define an operation as a function, rather than a method?
Well, functions have the benefit that, unlike methods(*), they are objects -- so you can pass them around, put them in collections, assign them to variables. And they have methods like compose() and andThen() which return a new function that combines this function with another.
So you can do things like:
Map<String,Function<String,String> nameTranslationStrategies = new HashMap<>();
nameTranslationStrategies.put(
"no change", x -> x);
nameTranslationStrategies.put(
"to first-last",
MiscellaneousFunctions.toFirstLastFunction);
nameTranslationStrategies.put(
"capitalised first-last",
MiscellaneousFunctions.toFirstLastFunction
.andThen( s -> s.toUpperCase());
...
String nameTranslationOption = config.getProperty("nameTranslationOption");
String name = nameTranslationStrategies
.get(nameTranslationOption)
.apply(inputString);
Java programmers managed for decades without this feature -- functions didn't exist until Java 8. But you can do lots of neat things with them.
Even so, this isn't a reason to write your code as a Function bound to a static variable, since you can access ordinary methods as functions using the :: syntax:
Function<Double,Double> logarithm = Math::log;
double x = logarithm.apply(2.0);
Note also, that you've used a long-winded syntax to define your function:
public static Function<String, String> slimify = new Function<String, String>() {
#Override
public String apply(String s) {
return "slim says " + s;
}
}
... can be written as:
public static Function<String,String> slimify = s -> {
return "slim says " + s;
}
... or even (since this one's a one-liner)
public static Function<String,String> slimify = s -> "slim says " + s;
It's good to know the long-winded way, because it shows how functions work behind the scenes. But in real world code, the shorter form is the way to go, as it is more expressive: the intent of the code isn't hidden by clutter. This is such a quick and easy way of expressing a function, that people often use them in-line rather than assign them to a variable -- as I have done in the map example above.
(*) I said that methods are not objects. This isn't strictly true -- partly because you can get one as an object using ::, but also because you can use Java's Reflection API to access classes and methods as objects. But you don't want to use Reflection, unless you really know you need to.
Math.min() is a public static method called min, your Function is a Function object, it's not a method. Your object has a method apply and you have to use that method for what you want to achieve, like this:
MiscellaneousFunctions.ToFirstLastFunction.apply(something)
I'm working on translating some code from Java to C# but am having some trouble, maybe someone out there can help?
I have problems trying to replicate anonymous interface implementations that are widely used in Java, but have no idea how to.
An example is:
List<DATA> queue1 = new ArrayList<DATA>(dataSet);
// Sort by distance to the first promoted data
Collections.sort(queue1, new Comparator<DATA>() {
#Override
public int compare(DATA data1, DATA data2) {
double distance1 = distanceFunction.calculate(data1, promoted.first);
double distance2 = distanceFunction.calculate(data2, promoted.first);
return Double.compare(distance1, distance2);
}
});
I have problems trying to replicate the inline functions that are widely used in Java
These are not inline functions, that's anonymous classes implementing a specific interface.
C# provides delegates that you can define inline or in a separate function.
Here is an example of sorting a List<DATA> in place using the Comparison<T> delegate:
List<DATA> queue = new List<DATA>();
queue.Sort(
(left, right) => {
double distance1 = distanceFunction.Calculate(left, promoted.first);
double distance2 = distanceFunction.Calculate(right, promoted.first);
return Double.Compare(distance1, distance2);
}
);
Note that in order for this to work, the distanceFunction variable needs to be in scope at the spot where you invoke queue.Sort. It can be a local variable defined above the invocation point, or a member variable/property of the class enclosing the function that makes the call.
In C# you end up using delegates instead of interfaces in may cases, especially in cases like this where it's likely the caller will want to define the method inline. You can use a lambda to define an anonymous method inline where any delegate is expected.
List<String> list = new List<String> { "B", "D", "E" };
list.Sort((a, b) => a.CompareTo(b));
There is no equivalent to Java's anonymous interface implementations in C#, so if there is an interface required (which isn't the case for sorting a List) you'll need to create a named class to implement it.
C# uses the concept of delegates in the place of anonymous interface implementations.
Assuming you've replaced ArrayList<DATA> with the .Net List<DATA>:
IEnumerable<DATA> sorted =
queue1.OrderBy(q => distanceFunction.calculate(q, promoted.first));
assume that you have an a List of Data objects in c#:
queue1.OrderBy(a => distanceFunction.Calculate(a, promoted.First));
If you want something that parallels the original Java, then:
internal virtual void test()
{
List<int> queue1 = new List<int>(dataSet);
queue1.Sort(new ComparatorAnonymousInnerClassHelper());
}
private class ComparatorAnonymousInnerClassHelper : IComparer<int>
{
public virtual int compare(int data1, int data2)
{
double distance1 = distanceFunction.calculate(data1, promoted.first);
double distance2 = distanceFunction.calculate(data2, promoted.first);
return distance1.CompareTo(distance2);
}
}
Are there any extensions for the Java programming language that make it possible to create nested functions?
There are many situations where I need to create methods that are only used once in the context of another method or for-loop. I've been unable to accomplish this in Java so far, even though it can be done easily in JavaScript.
For example, this can't be done in standard Java:
for(int i = 1; i < 100; i++){
times(2); // Multiply i by 2 and print i
times(i); // Square i and then print the result
public void times(int num){
i *= num;
System.out.println(i);
}
}
Java 8 introduces lambdas.
java.util.function.BiConsumer<Integer, Integer> times = (i, num) -> {
i *= num;
System.out.println(i);
};
for (int i = 1; i < 100; i++) {
times.accept(i, 2); //multiply i by 2 and print i
times.accept(i, i); //square i and then print the result
}
The () -> syntax works on any interface that defines exactly one method. So you can use it with Runnable but it doesn't work with List.
BiConsumer is one of many functional interfaces provided by java.util.function.
It's worth noting that under the hood, this defines an anonymous class and instantiates it. times is a reference to the instance.
The answer below is talking about the closest you can get to having nested functions in Java before Java 8. It's not necessarily the way I'd handle the same tasks which might be handled with nested functions in JavaScript. Often a private helper method will do just as well - possibly even a private helper type, which you create an instance of within the method, but which is available to all methods.
In Java 8 of course, there are lambda expressions which are a much simpler solution.
The closest you can easily come is with an anonymous inner class. That's as close as Java comes to closures at the moment, although hopefully there'll be more support in Java 8.
Anonymous inner classes have various limitations - they're obviously rather wordy compared with your JavaScript example (or anything using lambdas) and their access to the enclosing environment is limited to final variables.
So to (horribly) pervert your example:
interface Foo {
void bar(int x);
}
public class Test {
public static void main(String[] args) {
// Hack to give us a mutable variable we can
// change from the closure.
final int[] mutableWrapper = { 0 };
Foo times = new Foo() {
#Override public void bar(int num) {
mutableWrapper[0] *= num;
System.out.println(mutableWrapper[0]);
}
};
for (int i = 1; i < 100; i++) {
mutableWrapper[0] = i;
times.bar(2);
i = mutableWrapper[0];
times.bar(i);
i = mutableWrapper[0];
}
}
}
Output:
2
4
10
100
Is that the output you get from the JavaScript code?
I think that the closest you can get to having nested functions in Java 7 is not by using an anonymous inner class (Jon Skeet's answer), but by using the otherwise very rarely used local classes. This way, not even the interface of the nested class is visible outside its intended scope and it's a little less wordy too.
Jon Skeet's example implemented with a local class would look as follows:
public class Test {
public static void main(String[] args) {
// Hack to give us a mutable variable we can
// change from the closure.
final int[] mutableWrapper = { 0 };
class Foo {
public void bar(int num) {
mutableWrapper[0] *= num;
System.out.println(mutableWrapper[0]);
}
};
Foo times = new Foo();
for (int i = 1; i < 100; i++) {
mutableWrapper[0] = i;
times.bar(2);
i = mutableWrapper[0];
times.bar(i);
i = mutableWrapper[0];
}
}
}
Output:
2
4
10
100
Such methods are sometimes called closures. Have a look at Groovy – perhaps you will prefer it to Java. In Java 8 there will probably be closures as well (see JSR335 and deferred list).
For non-argument method you can create Runnable object
private static void methodInsideMethod(){
Runnable runnable = new Runnable(){
#Override
public void run(){
System.out.println("Execute something");
}
};
for(int i = 0; i < 10; i++){
runnable.run();
}
}
Consider making an anonymous local class and using its initializer block to do the work:
public class LocalFunctionExample {
public static void main(final String[] args) {
for (final int i[] = new int[] { 1 }; i[0] < 100; i[0]++) {
new Object() {
{
times(2); //multiply i by 2 and print i
times(i[0]); //square i and then print the result
}
public void times(final int num) {
i[0] *= num;
System.out.println(i[0]);
}
};
}
}
}
Output:
2
4
10
100
(The "final wrapper trick" is not automatically required with this technique, but was needed here to handle the mutation requirement.)
This works out to be almost as concise as the lambda version, but you get to use whatever method signatures you want, they get to have real parameter names, and the methods are called directly by their names - no need to .apply() or whatnot. (This kind of thing sometimes makes IDE tooling work a little better too.)
I don't know if anyone else has figured this out, but apparently you can do magic with the var keyword that comes with Java 10 and above. This saves you from having to declare an interface if you don't have one that will work for you.
public class MyClass {
public static void main(String args[]) {
var magic = new Object(){
public void magic(){
System.out.println("Hello World!");
}
};
magic.magic();
}
}
I have tested it and it works. I haven't found a Java compiler that lets you do a simple share yet.
I hate to use the forbidden word but you could use a goto statement to create an an effective subroutine inside the method. It is ugly and dangerous but much easier than what was shown in previous answers. Although the private method with a call inside of the first method is much better, and serves you needs just fine. I don't know why you would want to use a nested method for something as simple as this.