What does ()->{} represent in java?. Any help would be highly appreciated.
It's a lambda expression, basically a concise way of writing a function. ()->{} is a function that takes no arguments and does nothing. A longer way of writing the same thing:
new Runnable() {
#Override
public void run() {
// nothing
}
};
Let's consider old way of writing functions(i.e methods) in java.
//lets assume this is inside calculate class
public int sum(int a, int b){
return a+b;
}
in java 8 we have something called lambda's in which we have concept called passing behaviours(methods) to another behaviour(methods).
in those case we use syntax like (a,b) -> return a+b;
BiFunction<Integer,Integer,Integer> sum= (a,b)->{
return a+b;
};
System.out.println(sum.apply(1, 2));
Even we can store Function in a variable and pass to another function. you
can see here
now lets see about syntax (a,b) ->{ return a + b};
(a,b) are arguments to function;
and the line of code inside {} represent the behaviour. -> is to separate
both left and right expressions.
you can explore more about java8 and lambda over here
Related
So... not entirely sure if this has been answered before, though I suspect it has and I simply didn't understand it with my current knowledge of the language. As such, a tad bit further of an explanation may be nice, the thread I believe that this may be a duplicate of is
Java Pass Method as Parameter
The basic idea of what I would like to do is something like this:
public void doStuff(String parameter, int parameter, Action/Method/Scope/thing action){
for(parameters){
action();
}
}
which would be called like this:
String parameter1;
int parameter2;
doStuff(parameter1, parameter2){
action
}
this is really generic. Sorry about not having anything specific now. The main thing I'm thinking of is that I've been trying to make an "artillery game" similar to Arcanists (target), or maybe gravitee wars (as a more recent/popular example) the annoying bit is I am frequently working with editing images at a pixel level because the generic bufferedImage/graphic/whatever the normal one & GreenfootImage (greenfoot is the environment I'm using) lack what I want.
really tired right now, please be patient with me. if some of this looks odd of incoherent feel free to ask for clarification, I'm not always the easiest to understand when I'm typing tiredly.
To "pass a method" in Java 8, you need a matching functional interface, i.e. an interface with only one method, whose parameters and return type matches the method you want to pass.
You can use one of the standard methods in the java.util.function package, or you can write your own. E.g. the standard interfaces has various methods with 0, 1, or 2 parameters.
Since your parameters are different type, you can use BiFunction, or you could create your own like this:
public interface StringIntConsumer {
void accept(String s, int i);
}
You can now write code to accept such a method:
public void doStuff(String text, int count, StringIntConsumer action) {
for (int i = 0; i < count; i++) {
action.accept(text, i);
}
}
Then call it using a Lambda Expression:
doStuff("Foo", 10, (name, idx) -> {
// use name and idx here
// will be called 10 times with idx value 0-9
});
As you can see, the parameter names don't need to match.
You have described a BiFunction<T, U, R>,
static <T, U, R> R doStuff(T t, U u, BiFunction<T, U, R> func) {
return func.apply(t, u);
}
And you might call it like
public static void main(String[] args) {
System.out.println(doStuff("Hello", 1, (x, y) -> x + " " + y));
}
which just prints "Hello 1" - but it wasn't clear what action you wanted to do.
In my JavaFX, I attempted to have an ObservableMap<String, String> and a MapChangeListener that listens to keys and values changes(adding/removing a key or the corresponding value) and then does its job.
To make the listener be effective, the method to implement is:
void onChanged(MapChangeListener.Change<? extends K,? extends V> change)
What I first did, with a lambda expression, that doesn't generate any error:
map.addListener((MapChangeListener.Change<? extends String, ? extends String> change) -> {
//code here to implement onChange method
}
And here is what I discovered, that still doesn't generate any error:
map.addListener((MapChangeListener<String, String>) change -> {
//code here to implement onChange method
}
Note the position of the round brackets in this two different examples. The second seems to me to be a cast, but I really don't understand why this second option works.
Can anyone explain me this, please?
P.S.: Actually, I came accross this because I was dealing with a
ObservableMap<String, List<String>>,
that is a multimap, and the first "way" of the two above didn't work (with the right adjustments). /EDIT: I tried again with the first "way" and actually it does work, there was an error on the code I didn't notice END EDIT/. Then I tried with the second option, and it did work, and I was dazed. Then I discovered this same "behaviour" with a simple map <String, String> and this question has arisen.
These two are equivalent. The first one, you are defining the parameter of the lambda expression - note that your bracket covers the whole change parameter. This allows the compiler to know which overload to match it against.
The second one is simply a cast. You are telling the compiler what kind of method signature to match this lambda against. (MapChangeListener<String, String>) casts the whole lambda expression into a MapChangeListener, so the compiler knows that it really is addListener(MapChangeListener). Since you have defined the single parameter defined by MapChangeListener, the compiler doesn't complain that it is wrong either.
Edit
Now that I have a bit more time, I would give you some concrete example that will help you understand a little more in depth.
public class Foo {
public final void bar(IntfA a) {}
public final void bar(IntfB b) {}
public final void bar(IntfC c) {}
}
#FunctionalInterface
public interface IntfA {
void doSomething(Double a);
}
#FunctionalInterface
public interface IntfB {
void doSomething(Integer a);
}
#FunctionalInterface
public interface IntfC {
void doSomething(Double a);
}
public class Test {
public static void main(String[] args)
{
Foo foo = new Foo();
foo.bar(a -> {}); // Ambiguous
foo.bar((Integer a) -> {}); // Okay, this is IntfB
foo.bar((Double a) -> {}); // Ambiguous between IntfA and IntfC
foo.bar((IntfC) a -> {}); // No longer ambiguous since you specified that it's IntfC
foo.bar((IntfC) (a, b) -> {}); // Method signature does not match IntfC
}
}
Edit 2
It seems like you need a little more help here.
When you define a method bar(IntfA), you are expecting an object of IntfA, regardless whether IntfA is an interface type or a class type.
Then, lambda expressions are just compile-time convenient syntax. When I write foo.bar((Integer a) -> {}), the compiler will eventually turn it into Java bytecodes (within .class file) that is equivalent to this:
foo.bar(new IntfB() {
public void doSomething(Integer a) {
}
});
That equivalence is what we call Anonymous Class.
The biggest and possibly only difference in using lambda is, it makes your code shorter. Sometimes it makes your code more readable, sometimes it makes your code less readable.
Since lambda reduces the amount of things that you need to type out, it is very easy to have a lambda expression that is ambiguous for the compiler when there are overload methods like in the example. Remember that the compiler needs to figure out which overload first, then it will help you to instantiate the object for you.
When you write foo.bar((Double a) -> {}), the compile notices that you have a lambda expression that takes in one Double parameter and returns nothing. It will then look at the three overloads of bar(). It notices that both bar(IntfA) and bar(IntfC) takes in a functional interface, and both interface's method takes in one Double parameter and returns nothing. At this point, the compiler is not sure whether it should generate bytecodes equivalent to which two set of codes:
Choice 1:
foo.bar(new IntfA() {
public void doSomething(Double a) {
}
});
Choice 2:
foo.bar(new IntfC() {
public void doSomething(Double a) {
}
});
If you write foo.bar((IntfC) a -> {}), you are already hinting to the compiler that you want it to match foo.bar(IntfC) overload. The compiler sees that you have one parameter of unknown type, but since you have already tell it to match to IntfC, it will assume that parameter is Double.
Now to the last part, calling foo.bar(IntfA) doesn't automatically call the doSomething(Double a) method specified by IntfA. In my example the bar() methods did nothing, but normally people would write something useful.
Example again:
public final void bar(IntfB obj) {
if (obj == null)
System.out.println("I was waiting for an IntfB object but I got nothing!");
else
obj.doSomething(100);
}
foo.bar((Integer a) -> {
System.out.println("I got " + a + " marks for my exam!");
});
This causes "I got 100 marks for my exam!" to be printed on the console.
Lambda in reality doesn't require its type to be expressed unless there is an ambiguity.
If you would not type change it would conflict with addListener(InvalidationListener) that has the same argument length. There are 2 ways of solving this, either by explicitly expressing the type (your first snippet) or by directing the compiler to the correct overload (second), which has nothing to do with lambda semantics.
To reiterate the second point, say you have
void print(String s)
and
void print(Integer i)
calling
print(null) would cause an ambiguity. The solution is print((String)null) which is of course not a type cast, as null has no type, but rather a compiler note.
Say I have the following interface:
#FunctionalInterface
public interface First {
int fun(int a);
}
and also
#FunctionalInterface
public interface Second extends First {
default int fun(int a) { fun(a, a); }
int fun(int a, int b);
}
Then if I have a method somewhere that takes a First I can do, for example:
methodThatTakeFirst(val -> val + 1);
But I also want to be able to pass a Second, like:
methodThatTakeFirst((v1, v2) -> v2 * v2);
However this only works if I cast the lambda like this:
methodThatTakeFirst((Second) (v1, v2) -> v2 * v2);
My question is: is there a way to design this pattern without having to cast the lambdas to the subinterface? Or what would be the most elegant way to handle this scenarios?
You could overload methodThatTakeFirst, so that it also accepts an instance of Second as an argument, and delegate to methodThatTakeFirst(First first):
void methodThatTakeFirst(First first) {
// play with first
}
void methodThatTakeFirst(Second second) {
methodThatTakeFirst((First) second); // casting necessary
}
The cast is crucial, so that the compiler actually delegates to methodThatTakeFirst(First first), otherwise you'd end up with a StackOverflowError.
Whether this is a good design or not, I don't know, but I think it's outside the scope of this question.
Maybe just add another lambda?
void secondMethod(Second second) {
methodThatTakeFirst(x-> second.fun(x,x));
}
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.
I'm writing an expression evaluator in Java. I would like the ability to add more operators (I currently have only (, ), +, -, *, /, and ^). Currently, my code looks like this:
case '+':
return a+b;
case '-':
return a-b;
case '*':
return a*b;
...
This works for my code because I have only a few operators. However, if I were to add more operators, the code would become cluttered. I am looking for a way to map an operator (represented by a String) to a method. For example, "ln" would be mapped to Math.log(), "^" would be mapped to Math.pow(), etc.
How would I go about doing this? If it's not feasible, what are some alternatives?
Not possible unless you want to use reflection. A solution without reflection could look like this:
public interface Operation {
int apply(int... operands);
}
public abstract class BinaryOperation implements Operation {
#Override
public int apply(int... operands) {
return apply(operands[0], operands[1]);
}
abstract int apply(int a, int b);
}
Map<String, Operation> operations = new HashMap<String, Operation>() {{
put("+", new Operation() {
#Override
public int apply(int... operands) {
return operands[0] + operands[1];
}
});
put("-", new BinaryOperation() {
#Override
public int apply(int a, int b) {
return a - b;
}
});
}};
You could use template methods.
public enum Functions {
ADD() {
#Override public int execute(int a, int b) {
return a+b;
}
},
SUB() {
#Override public int execute(int a, int b) {
return a-b;
}
};
//Template method
public abstract int execute(int a, int b);
}
Then map between string and enum with Map<String, Functions> functionMap
So if you want to add you can do functionMap.put("+", Functions.ADD);
Then call functionMap.get("+").execute(a,b);
I suppose you could also use varargs if different functions take different numbers of arguments.
public abstract int execute (Integer... inputs);
This example is modified from Making the Most of Java 5.0: Enum Tricks and what #duffymo said.
Building on the Operation suggestion above, a Map<String, Operation> would manage it with a lookup.
I think your setup is the optimal setup as I cannot think of a way to do this easily in java, although in a language like c/c++ you could easily map strings to function pointers but I don't think there's an equivalent of this in Java AFAIK. The beauty of switch statements though is that they actually avoid the clutter because visually you can easily see what the case of the switch statement is and just look for the appropriate case that you want (although for strings you made need a giant if cascade since == operator is not overloaded in java for string comparison).
Edit: See Ryan Stewarts comment, they use OOP ways of doing exactly what you want. Although that seems more cluttered than your switch statement in some cases.