Skip to content

Commit 5fc0f92

Browse files
author
Ramkumar Manavalan
committed
first commit
0 parents  commit 5fc0f92

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

ClosureDemo.java

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package funcprog;
2+
import java.util.function.BiFunction;
3+
import java.util.function.Function;
4+
import java.util.function.Supplier;
5+
6+
public class ClosureDemo {
7+
8+
public static void main(String[] args) {
9+
closureType1Demo();
10+
closureType2Demo();
11+
closureType3Demo();
12+
closureType4Demo();
13+
closureType5Demo();
14+
closureType6Demo();
15+
closureType7Demo();
16+
}
17+
18+
/*
19+
CLOSURES:
20+
A closure is the combination of a function bundled together (enclosed) with
21+
references to its surrounding state (the lexical environment). In other words,
22+
a closure gives you access to an outer function’s scope from an inner function.
23+
24+
Closures are commonly used to give objects data privacy. When you use closures for data privacy,
25+
the enclosed variables are only in scope within the containing (outer) function.
26+
You can’t get at the data from an outside scope except through the object’s privileged methods.
27+
In JavaScript, any exposed method defined within the closure scope is privileged.
28+
29+
Closures are also used when we need to partially apply functions and also for currying. The returned partial function is the privileged function
30+
that remembers the applied parameters.
31+
32+
Closures are basically stateful functions
33+
*/
34+
35+
@FunctionalInterface // optional
36+
public interface NumToTextConverter {
37+
String convert(int x);
38+
}
39+
40+
// Type 1: Closure with custom Functional Interface and inner class
41+
static void closureType1Demo() {
42+
NumToTextConverter textOfWeekday = new NumToTextConverter() {
43+
String [] weeks = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
44+
@Override
45+
public String convert(int num) {
46+
return (num > 0 && num <= weeks.length) ? weeks[num-1] : null;
47+
};
48+
};
49+
System.out.println(textOfWeekday.convert(1)); // Mon
50+
}
51+
52+
// Type 2: Closure with custom Functional Interface & Lambda expression
53+
static void closureType2Demo() {
54+
NumToTextConverter textOfWeekday = num -> {
55+
String [] weeks = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
56+
return (num > 0 && num <= weeks.length) ? weeks[num-1] : null;
57+
};
58+
System.out.println(textOfWeekday.convert(2)); // Tue
59+
}
60+
61+
// Type 3: Closure with pre-defined Functional Interface, with Lambda expression
62+
static void closureType3Demo() {
63+
Function<Integer, String> getTextOfWeekday = num -> {
64+
String [] weeks = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
65+
return (num > 0 && num <= weeks.length) ? weeks[num-1] : null;
66+
};
67+
System.out.println(getTextOfWeekday.apply(3)); // Wed
68+
}
69+
70+
// Type 4: [ACTUAL] Closure with pre-defined Functional Interface, with Lambda expression, with inner function
71+
// having access to parent scope (String [] weeks)
72+
static Function<Integer, String> getTextOfWeekday() {
73+
String [] weeks = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
74+
return num -> (num > 0 && num <= weeks.length) ? weeks[num-1] : null; // privileged inner function that encloses/remembers weeks
75+
}
76+
static void closureType4Demo() {
77+
System.out.println(getTextOfWeekday().apply(4)); // Thu
78+
}
79+
80+
// Type 5: Closure with pre-defined Functional Interface, with Lambda expression, with inner function having access to parent scope
81+
// parent scope, in this scope, is nothing but state passed by client
82+
static Function<Integer, String> getTextOfWeekday(String [] weeks) {
83+
return num -> (num > 0 && num <= weeks.length) ? weeks[num-1] : null;
84+
}
85+
static void closureType5Demo() {
86+
Function<Integer, String> getArabTextOfWeekday = getTextOfWeekday(new String[]{ "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu"});
87+
Function<Integer, String> getIndianTextOfWeekday = getTextOfWeekday(new String[]{ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"});
88+
System.out.println(getArabTextOfWeekday.apply(5)); // Tue
89+
System.out.println(getIndianTextOfWeekday.apply(5)); // Fri
90+
}
91+
92+
93+
// Type 6: Closure with lambda and with pre-defined Functional Interface, demonstrating the fact that
94+
// Lambdas/CLosures in Java 8 cover values and not variables
95+
static Supplier<Integer> getNextInSequence() {
96+
int lastInSequence = 0;
97+
return () -> lastInSequence + 1; // ++lastSequence will be a compiler error coz Java 8 forces the parent scope variables (non heaps) to be immutable
98+
};
99+
static void closureType6Demo() {
100+
System.out.println(getNextInSequence().get()); // 1
101+
System.out.println(getNextInSequence().get()); // 1 and not 2
102+
}
103+
104+
// Type 7: Closure, used to partially apply
105+
static Function<Integer, Integer> partial(BiFunction<Integer, Integer, Integer> fn, Integer x) {
106+
return y -> fn.apply(x, y); // privileged inner function that remembers x (value and not variable)
107+
}
108+
static void closureType7Demo() {
109+
BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
110+
Function<Integer, Integer> tenAdder = partial(add, 10);
111+
System.out.println(tenAdder.apply(5));
112+
Function<Integer, Integer> twentyAdder = partial(add, 20);
113+
System.out.println(twentyAdder.apply(5));
114+
}
115+
116+
}

0 commit comments

Comments
 (0)