Java Blocks, Closures, Lambdas... simply explained [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
For those who ever wrote in C, C++ or ObjectiveC, understand Blocks is very simple. Why it's so difficult to get the concept in Java (8)?
I will answer my question!

Block
Just a list of statements surrounded by curly braces. That's all. A block is executed by executing its individual statements in sequence. It's nothing like the thing called a "block" in, for example, the Ruby programming language.
Closure
Java does not have closures, but it has something that looks like one:
int limit = ...;
Thread t = new Thread(new Runnable() {
#Override
public void run() {
for (int i=0 ; i<limit ; i++) { ... }
}
});
That may look like the run() method refers to the variable limit in the outer scope, but it won't compile unless the variable limit is effectively immutable. What's really happening here is that the anonymous inner class has a member variable named limit, and a hidden constructor that takes an argument named limit, and the value is supplied to the constructor by copying the value of limit from the surrounding scope.
Lambda
More smoke and mirrors. The value of a lambda expression in Java is not a function: It's an instance of an anonymous inner class that implements a functional interface. The same code that I wrote above could be written more concisely as a Java lambda expression:
int limit = ...;
Thread t = new Thread(() -> {
for (int i=0 ; i<limit ; i++) { ... }
});
Java8 introduces the idea of an #Functional interface type which must declare exactly one method. In this case, they've retconned the java.lang.Runnable class to be #Functional
When the compiler reads the code above, it knows to make the anonymous class implement the Runnable interface because that's the only type that is accepted by the Thread constructor, and it knows that the body of the lambda should become the run() method, because that's the only method declared by Runnable.

All you need to understand is “type”.
A variable has a type. Eg:
int i, double d…
An object has a type (a class). Eg:
String s, Number n, Object o, MyClass m…
A function has a type. Eg:
void function () <= this type is: a function with no return and no param.
void function (type param) <= this type is: a function with no return with a param of type ‘type’
type function (type param) <= this type is: a function with a return of type ‘type’ and a param of type ‘type’
What is a block/closure/lambda?
It is basically a local function of a given type passed to an other function as parameter.
So we heard: a function that takes a function of a given type as parameter.
And the function which receive the function and launches it!
The main usage is: CallBack and Comparaison functions. But the dream up is open.
We can draw that as:
type function(type function_param) {
excute the function_param
}
How to say this in Java.
1/ declare the type of the block/closure/lambda
2/ create the function (in a class or not) which get that kind of type as param
3/ create the local function of the type of the block/closure/lambda
4/ pass it as param to the function which use it.
Eg:
// 1 declaring the type of block/closure/lambda
interface CallBack {
public int function(String string);
}
class MyClass {
private String name;
MyClass(String name) { this.name = name; }
void display () { System.out.println(this.name); }
// 2 creating the function that which that kind of type as param
int myFunction(CallBack funcCallBack) {
return funcCallBack.function(name);
}
}
public class Main {
public static void main(String[] args) {
// 3 Create the local function of the type of the block/closure/lambda
CallBack message = (String string) -> {
System.out.println("Message: "+string);
return 1;
};
MyClass mc = new MyClass("MyClass");
mc.display();
// 4 pass it as param to the function which use it.
int res = mc.myFunction(message);
System.out.println(res);
}
}
output
MyClass
Message: MyClass
1

Related

Java - Pass a method call into a method [duplicate]

This question already has answers here:
Java Pass Method as Parameter
(17 answers)
Closed 8 years ago.
In Java, how can one pass a function as an argument of another function?
Java 8 and above
Using Java 8+ lambda expressions, if you have a class or interface with only a single abstract method (sometimes called a SAM type), for example:
public interface MyInterface {
String doSomething(int param1, String param2);
}
then anywhere where MyInterface is used, you can substitute a lambda expression:
class MyClass {
public MyInterface myInterface = (p1, p2) -> { return p2 + p1; };
}
For example, you can create a new thread very quickly:
new Thread(() -> someMethod()).start();
And use the method reference syntax to make it even cleaner:
new Thread(this::someMethod).start();
Without lambda expressions, these last two examples would look like:
new Thread(new Runnable() { someMethod(); }).start();
Before Java 8
A common pattern would be to 'wrap' it within an interface, like Callable, for example, then you pass in a Callable:
public T myMethod(Callable<T> func) {
return func.call();
}
This pattern is known as the Command Pattern.
Keep in mind you would be best off creating an interface for your particular usage. If you chose to go with callable, then you'd replace T above with whatever type of return value you expect, such as String.
In response to your comment below you could say:
public int methodToPass() {
// do something
}
public void dansMethod(int i, Callable<Integer> myFunc) {
// do something
}
then call it, perhaps using an anonymous inner class:
dansMethod(100, new Callable<Integer>() {
public Integer call() {
return methodToPass();
}
});
Keep in mind this is not a 'trick'. It's just java's basic conceptual equivalent to function pointers.
You could use Java reflection to do this. The method would be represented as an instance of java.lang.reflect.Method.
import java.lang.reflect.Method;
public class Demo {
public static void main(String[] args) throws Exception{
Class[] parameterTypes = new Class[1];
parameterTypes[0] = String.class;
Method method1 = Demo.class.getMethod("method1", parameterTypes);
Demo demo = new Demo();
demo.method2(demo, method1, "Hello World");
}
public void method1(String message) {
System.out.println(message);
}
public void method2(Object object, Method method, String message) throws Exception {
Object[] parameters = new Object[1];
parameters[0] = message;
method.invoke(object, parameters);
}
}
Lambda Expressions
To add on to jk.'s excellent answer, you can now pass a method more easily using Lambda Expressions (in Java 8). First, some background. A functional interface is an interface that has one and only one abstract method, although it can contain any number of default methods (new in Java 8) and static methods. A lambda expression can quickly implement the abstract method, without all the unnecessary syntax needed if you don't use a lambda expression.
Without lambda expressions:
obj.aMethod(new AFunctionalInterface() {
#Override
public boolean anotherMethod(int i)
{
return i == 982
}
});
With lambda expressions:
obj.aMethod(i -> i == 982);
Here is an excerpt from the Java tutorial on Lambda Expressions:
Syntax of Lambda Expressions
A lambda expression consists of the following:
A comma-separated list of formal parameters enclosed in parentheses. The CheckPerson.test method contains one parameter, p,
which represents an instance of the Person class.Note: You
can omit the data type of the parameters in a lambda expression. In
addition, you can omit the parentheses if there is only one parameter.
For example, the following lambda expression is also valid:
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
The arrow token, ->
A body, which consists of a single expression or a statement block. This example uses the following expression:
p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
If you specify a single expression, then the Java runtime evaluates the expression and then returns its value. Alternatively,
you can use a return statement:
p -> {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
A return statement is not an expression; in a lambda expression, you must enclose statements in braces ({}). However, you do not have
to enclose a void method invocation in braces. For example, the
following is a valid lambda expression:
email -> System.out.println(email)
Note that a lambda expression looks a lot like a method declaration;
you can consider lambda expressions as anonymous methods—methods
without a name.
Here is how you can "pass a method" using a lambda expression:
Note: this uses a new standard functional interface, java.util.function.IntConsumer.
class A {
public static void methodToPass(int i) {
// do stuff
}
}
import java.util.function.IntConsumer;
class B {
public void dansMethod(int i, IntConsumer aMethod) {
/* you can now call the passed method by saying aMethod.accept(i), and it
will be the equivalent of saying A.methodToPass(i) */
}
}
class C {
B b = new B();
public C() {
b.dansMethod(100, j -> A.methodToPass(j)); //Lambda Expression here
}
}
The above example can be shortened even more using the :: operator.
public C() {
b.dansMethod(100, A::methodToPass);
}
Thanks to Java 8 you don't need to do the steps below to pass a function to a method, that's what lambdas are for, see Oracle's Lambda Expression tutorial. The rest of this post describes what we used to have to do in the bad old days in order to implement this functionality.
Typically you declare your method as taking some interface with a single method, then you pass in an object that implements that interface. An example is in commons-collections, where you have interfaces for Closure, Transformer, and Predicate, and methods that you pass implementations of those into. Guava is the new improved commons-collections, you can find equivalent interfaces there.
So for instance, commons-collections has org.apache.commons.collections.CollectionUtils, which has lots of static methods that take objects passed in, to pick one at random, there's one called exists with this signature:
static boolean exists(java.util.Collection collection, Predicate predicate)
It takes an object that implements the interface Predicate, which means it has to have a method on it that takes some Object and returns a boolean.
So I can call it like this:
CollectionUtils.exists(someCollection, new Predicate() {
public boolean evaluate(Object object) {
return ("a".equals(object.toString());
}
});
and it returns true or false depending on whether someCollection contains an object that the predicate returns true for.
Anyway, this is just an example, and commons-collections is outdated. I just forget the equivalent in Guava.
Java supports closures just fine. It just doesn't support functions, so the syntax you're used to for closures is much more awkward and bulky: you have to wrap everything up in a class with a method. For example,
public Runnable foo(final int x) {
return new Runnable() {
public void run() {
System.out.println(x);
}
};
}
Will return a Runnable object whose run() method "closes over" the x passed in, just like in any language that supports first-class functions and closures.
I used the command pattern that #jk. mentioned, adding a return type:
public interface Callable<I, O> {
public O call(I input);
}
I know this is a rather old post but I have another slightly simpler solution.
You could create another class within and make it abstract. Next make an Abstract method name it whatever you like. In the original class make a method that takes the new class as a parameter, in this method call the abstract method. It will look something like this.
public class Demo {
public Demo(/.../){
}
public void view(Action a){
a.preform();
}
/**
* The Action Class is for making the Demo
* View Custom Code
*/
public abstract class Action {
public Action(/.../){
}
abstract void preform();
}
}
Now you can do something like this to call a method from within the class.
/...
Demo d = new Demo;
Action a = new Action() {
#Override
void preform() {
//Custom Method Code Goes Here
}
};
/.../
d.view(a)
Like I said I know its old but this way I think is a little easier. Hope it helps.
Java does not (yet) support closures. But there are other languages like Scala and Groovy which run in the JVM and do support closures.

Why does functional interface with void return-type method accept any return-type method? [duplicate]

This question already has answers here:
Why does a Java method reference with return type match the Consumer interface?
(2 answers)
Why Java 8 Stream forEach method behaves differently?
(4 answers)
Closed 3 years ago.
We have this code:
public class Test {
public static Object foo() {
System.out.println("Foo");
return new Object();
}
public static void main(String[] args) {
J j = Test::foo;
j.m();
}
}
interface J {
void m();
}
And this code will work. The crucial line is
J j = Test::foo;
Although interface J declares it has a void function, Test::foo returns an Object.
While we can't override method while implementing interface (which is obvious).
This works only when interface's method is void, otherwise the code won't be compiled. Could someone tell why does this work in the way it works? :D
Although interface J declares it has a void function, Test::foo returns an Object.
It's inaccurate to say that Test::foo returns something. In different contexts, it could mean different things.
Supplier<Object> a = Test::foo;
J b = Test::foo;
Runnable c = Test::foo;
It's more accurate to say that Test::foo can represent a target type the functional method of which returns either void or Object.
It's an example of expression statement (jls-14.8).
If the target type's function type has a void return, then the lambda body is either a statement expression (§14.8) or a void-compatible block (§15.27.2).
...
An expression statement is executed by evaluating the expression; if the expression has a value, the value is discarded.
I am not sure what exactly is confusing you so here is some other way how you can look at your example.
J j = Test::foo;
can be rewritten as
J j = () -> Test.foo();
since it provides body to m() method from J functional interface and that method doesn't require any arguments (which is why it starts with () ->).
But that can be seen as shorter version of
J j = new J(){
public void m(){
Test.foo(); //correct despite `foo` returning value
}
};
which is correct, because Java allows us to ignore returned value of called method like in case of List#add(E element) which returns boolean value, but we still are allowed to write code like list.add(1) without having to handle returned value.

Why can this lambda expression assigned to different functional interfaces? [duplicate]

This question already has answers here:
Lambda 'special void-compatibility rule' - statement expression
(3 answers)
Why do Consumers accept lambdas with statement bodies but not expression bodies?
(3 answers)
Why does a Java method reference with return type match the Consumer interface?
(2 answers)
Consumer lambda in Java 8 [duplicate]
(2 answers)
Closed 4 years ago.
Given this method:
private static Integer return0() {
return 0;
}
I discovered a weird property of the following lambda expression:
() -> return0();
Does it actually return the value from the function it calls (which would make it a Supplier-Interface) or does it not return the value but only calls the function and returns void (which would make it a Runnable-Interface). Intuitively, I would expect the first case to be correct but could live with the second.
When trying to assign the statement:
Supplier<Integer> supplier2 = () -> return0();
Runnable runnable2 = () -> return0();
It turns out both lines do compile! Why would they allow that? It is completely ambiguous and really confusing!
EDIT:
Here is more code to demonstrate what I mean by confusing/ambigous:
public static void main(String[] args) {
callMe(() -> return0());
}
private static Integer return0() {
return 0;
}
private static void callMe(Supplier<Integer> supplier) {
System.out.println("supplier!");
}
private static void callMe(Runnable runnable) {
System.out.println("runnable!");
}
This all compiles well and upon execution prints "supplier!". I do not find it particularly intuitive that the first method is chosen but rather arbitrary.
The relevant part of the spec is Sec 15.27.3 (emphasis mine):
A lambda expression is congruent with a function type if all of the following are true:
The function type has no type parameters.
The number of lambda parameters is the same as the number of parameter types of the function type.
If the lambda expression is explicitly typed, its formal parameter types are the same as the parameter types of the function type.
If the lambda parameters are assumed to have the same types as the function type's parameter types, then:
If the function type's result is void, the lambda body is either a statement expression (§14.8) or a void-compatible block.
If the function type's result is a (non-void) type R, then either i) the lambda body is an expression that is compatible with R in an assignment context, or ii) the lambda body is a value-compatible block, and each result expression (§15.27.2) is compatible with R in an assignment context.
Your lambda body is a statement expression, and the function type's result is void.
In other words, it would be fine for you to write:
return0();
and ignore the return value in "regular" code, so it's fine to ignore the result value in a lambda too.
In terms of the question over ambiguity of overloads, there is no ambiguity in this case (it's easy to construct a case where there is ambiguity, e.g. another overload with a parameter that looks like Supplier but is a different interface, i.e. takes no parameters, returns a value).
You would have to read the spec in detail for the precise reasoning, but I think the most relevant section is Sec 15.12, which describes method invocation expressions, and the most useful quote from that is in Sec 15.12.2.5, which deals with selecting the most-specific overload:
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time error.
You can use a Supplier<Integer> in place of a Runnable (with a bit of a hand-wavy fudge) because you can simply ignore the return value; you can't use a Runnable in place of a Supplier<Integer> because it doesn't have a return value.
So a method taking the Supplier<Integer> is more specific than the method taking the Runnable, hence that is the one which is invoked.
If you get confused with lambda expressions, replace them with anonymous classes for a better understanding (IntelliJ IDEA can easily help you with that). The following code snippets are completely valid:
Supplier<Integer> supplier2 = () -> return0() is equivalent to:
Supplier<Integer> supplier2 = new Supplier<Integer>() {
#Override
public Integer get() {
return return0();
}
};
Runnable runnable2 = () -> return0() is equivalent to:
Runnable runnable2 = new Runnable() {
#Override
public void run() {
return0();
}
};
public static void main(String[] args) throws Exception
{
Supplier<Integer> consumer2 = Trial::return0;
Runnable runnable2 = Trial::return0;
run(Trial::return0);
}
private static Integer return0() {
return 0;
}
private static int run(Supplier<Integer> a)
{
System.out.println("supplier");
return a.get();
}
private static void run(Runnable r)
{
System.out.println("runnable");
r.run();
}
As far as method overloading is concerned, this code in class Trial prints "supplier".

Why does the following casting with method reference not produce a compilation error? [duplicate]

This question already has answers here:
Why does a Java method reference with return type match the Consumer interface?
(2 answers)
Closed 4 years ago.
public class SomeClass{
public static int someFunction(int a) {
return a;
}
public static void main(String[] args) {
Consumer<Integer> c = SomeClass::someFunction;
}
}
I'm not getting why: Consumer<Integer> c = SomeClass::someFunction;
is not producing a compilation error, since the function someFunction is a method with return value, and Consumer is representing methods with no return value
From the spec:
If the body of a lambda is a statement expression (that is, an
expression that would be allowed to stand alone as a statement), it is
compatible with a void-producing function type; any result is simply
discarded.
Same is true for method references.
It's more flexible that way. Suppose it was a compiler error to not use a return value when you called a method normally - that would be incredibly annoying. You'd end up having to use fake variables you didn't care about in some cases.
public class SomeClass
{
public static int someFunction(int a) {
return a;
}
public static void main(String[] args) {
someFunction(3); // "error" - ignoring return type
int unused = someFunction(3); // "success"
}
}
If you want a the full formal definition of what is acceptable, see 15.13.2. Type of a Method Reference.
This is called special void compatibility rule. For example how many times have you actually cared about List#add return type? Even if it does return true/false.
Pretty much the same thing here, you can invoke a method, but ignore its result. If you re-write your consumer as a lambda expression, it makes more sense:
Consumer<Integer> c = x -> {
SomeClass.someFunction(x);
return;
}
If I remember correctly from the JLS there are only some types that are allowed for this.
increment/decrement operations
method invocation
assignment
instance creation

How to pass a function as a parameter in Java? [duplicate]

This question already has answers here:
Java Pass Method as Parameter
(17 answers)
Closed 8 years ago.
In Java, how can one pass a function as an argument of another function?
Java 8 and above
Using Java 8+ lambda expressions, if you have a class or interface with only a single abstract method (sometimes called a SAM type), for example:
public interface MyInterface {
String doSomething(int param1, String param2);
}
then anywhere where MyInterface is used, you can substitute a lambda expression:
class MyClass {
public MyInterface myInterface = (p1, p2) -> { return p2 + p1; };
}
For example, you can create a new thread very quickly:
new Thread(() -> someMethod()).start();
And use the method reference syntax to make it even cleaner:
new Thread(this::someMethod).start();
Without lambda expressions, these last two examples would look like:
new Thread(new Runnable() { someMethod(); }).start();
Before Java 8
A common pattern would be to 'wrap' it within an interface, like Callable, for example, then you pass in a Callable:
public T myMethod(Callable<T> func) {
return func.call();
}
This pattern is known as the Command Pattern.
Keep in mind you would be best off creating an interface for your particular usage. If you chose to go with callable, then you'd replace T above with whatever type of return value you expect, such as String.
In response to your comment below you could say:
public int methodToPass() {
// do something
}
public void dansMethod(int i, Callable<Integer> myFunc) {
// do something
}
then call it, perhaps using an anonymous inner class:
dansMethod(100, new Callable<Integer>() {
public Integer call() {
return methodToPass();
}
});
Keep in mind this is not a 'trick'. It's just java's basic conceptual equivalent to function pointers.
You could use Java reflection to do this. The method would be represented as an instance of java.lang.reflect.Method.
import java.lang.reflect.Method;
public class Demo {
public static void main(String[] args) throws Exception{
Class[] parameterTypes = new Class[1];
parameterTypes[0] = String.class;
Method method1 = Demo.class.getMethod("method1", parameterTypes);
Demo demo = new Demo();
demo.method2(demo, method1, "Hello World");
}
public void method1(String message) {
System.out.println(message);
}
public void method2(Object object, Method method, String message) throws Exception {
Object[] parameters = new Object[1];
parameters[0] = message;
method.invoke(object, parameters);
}
}
Lambda Expressions
To add on to jk.'s excellent answer, you can now pass a method more easily using Lambda Expressions (in Java 8). First, some background. A functional interface is an interface that has one and only one abstract method, although it can contain any number of default methods (new in Java 8) and static methods. A lambda expression can quickly implement the abstract method, without all the unnecessary syntax needed if you don't use a lambda expression.
Without lambda expressions:
obj.aMethod(new AFunctionalInterface() {
#Override
public boolean anotherMethod(int i)
{
return i == 982
}
});
With lambda expressions:
obj.aMethod(i -> i == 982);
Here is an excerpt from the Java tutorial on Lambda Expressions:
Syntax of Lambda Expressions
A lambda expression consists of the following:
A comma-separated list of formal parameters enclosed in parentheses. The CheckPerson.test method contains one parameter, p,
which represents an instance of the Person class.Note: You
can omit the data type of the parameters in a lambda expression. In
addition, you can omit the parentheses if there is only one parameter.
For example, the following lambda expression is also valid:
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
The arrow token, ->
A body, which consists of a single expression or a statement block. This example uses the following expression:
p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
If you specify a single expression, then the Java runtime evaluates the expression and then returns its value. Alternatively,
you can use a return statement:
p -> {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
A return statement is not an expression; in a lambda expression, you must enclose statements in braces ({}). However, you do not have
to enclose a void method invocation in braces. For example, the
following is a valid lambda expression:
email -> System.out.println(email)
Note that a lambda expression looks a lot like a method declaration;
you can consider lambda expressions as anonymous methods—methods
without a name.
Here is how you can "pass a method" using a lambda expression:
Note: this uses a new standard functional interface, java.util.function.IntConsumer.
class A {
public static void methodToPass(int i) {
// do stuff
}
}
import java.util.function.IntConsumer;
class B {
public void dansMethod(int i, IntConsumer aMethod) {
/* you can now call the passed method by saying aMethod.accept(i), and it
will be the equivalent of saying A.methodToPass(i) */
}
}
class C {
B b = new B();
public C() {
b.dansMethod(100, j -> A.methodToPass(j)); //Lambda Expression here
}
}
The above example can be shortened even more using the :: operator.
public C() {
b.dansMethod(100, A::methodToPass);
}
Thanks to Java 8 you don't need to do the steps below to pass a function to a method, that's what lambdas are for, see Oracle's Lambda Expression tutorial. The rest of this post describes what we used to have to do in the bad old days in order to implement this functionality.
Typically you declare your method as taking some interface with a single method, then you pass in an object that implements that interface. An example is in commons-collections, where you have interfaces for Closure, Transformer, and Predicate, and methods that you pass implementations of those into. Guava is the new improved commons-collections, you can find equivalent interfaces there.
So for instance, commons-collections has org.apache.commons.collections.CollectionUtils, which has lots of static methods that take objects passed in, to pick one at random, there's one called exists with this signature:
static boolean exists(java.util.Collection collection, Predicate predicate)
It takes an object that implements the interface Predicate, which means it has to have a method on it that takes some Object and returns a boolean.
So I can call it like this:
CollectionUtils.exists(someCollection, new Predicate() {
public boolean evaluate(Object object) {
return ("a".equals(object.toString());
}
});
and it returns true or false depending on whether someCollection contains an object that the predicate returns true for.
Anyway, this is just an example, and commons-collections is outdated. I just forget the equivalent in Guava.
Java supports closures just fine. It just doesn't support functions, so the syntax you're used to for closures is much more awkward and bulky: you have to wrap everything up in a class with a method. For example,
public Runnable foo(final int x) {
return new Runnable() {
public void run() {
System.out.println(x);
}
};
}
Will return a Runnable object whose run() method "closes over" the x passed in, just like in any language that supports first-class functions and closures.
I used the command pattern that #jk. mentioned, adding a return type:
public interface Callable<I, O> {
public O call(I input);
}
I know this is a rather old post but I have another slightly simpler solution.
You could create another class within and make it abstract. Next make an Abstract method name it whatever you like. In the original class make a method that takes the new class as a parameter, in this method call the abstract method. It will look something like this.
public class Demo {
public Demo(/.../){
}
public void view(Action a){
a.preform();
}
/**
* The Action Class is for making the Demo
* View Custom Code
*/
public abstract class Action {
public Action(/.../){
}
abstract void preform();
}
}
Now you can do something like this to call a method from within the class.
/...
Demo d = new Demo;
Action a = new Action() {
#Override
void preform() {
//Custom Method Code Goes Here
}
};
/.../
d.view(a)
Like I said I know its old but this way I think is a little easier. Hope it helps.
Java does not (yet) support closures. But there are other languages like Scala and Groovy which run in the JVM and do support closures.

Categories

Resources