Created
June 9, 2018 02:40
-
-
Save iocat/0a4ae5944ae3065df453faa67049a8ce to your computer and use it in GitHub Desktop.
Lambda expression in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.function.*; | |
public class Lambda { | |
public static void main(String[] args) { | |
// In the object world of Java when everything is an object, you can't really pass function as "object." | |
// | |
// | |
// | |
// Unlike Java <1.8, Javascript allows you to have first-class functions or function as value which you can | |
// assign to variable, pass them around, return them! This is fundametal to functional programming, | |
// where behavior can be constructed on the fly much easier! | |
// Example in js | |
/* | |
var triple = function (x) {return x * 3; } | |
var double = x => x * 2 | |
var multiplyBy = function (factor){return x => x * factor } // returns a function that do multiplication | |
So in Java, how do we build behavior dynamically on the fly? We build objects that have specified behaviors. | |
Then we swap in other objects that have behaviors we desire. | |
Example: a cat can meow and another one can MEOW really loudly. This is how we build dynamic behavior | |
1. Way 1 | |
*/ | |
Meowable meowable = new SmallMeow(); | |
meowable.meow(); | |
meowable = new LoudMeow(); | |
meowable.meow(); | |
/* | |
This is quite a tedious task to add a new behavior, right? | |
If you want to add a new behavior such as GrumpyMeow, you would have to define a new class with that | |
name, and reimplement that same method! | |
2. Way 2 | |
In Java version 1.3, Java introduces anonymous inner class which allows us to define | |
an abstract class/interface's implementation inline. This makes it easier to define behavior | |
dynamically without naming them... Let's try to implement GrumpyMeow | |
*/ | |
// anonymous inner class | |
meowable = new Meowable(){ | |
@Override | |
public void meow(){ | |
System.out.println("GRURRRRRRRRRRMMMMMMMMMM!! MEOOOOOOOOOW!"); // a somewhat dramatic meow | |
} | |
}; | |
meowable.meow(); | |
/* | |
Better yet, this feature allows you to create class instance and implementation at the same | |
time without having to create a new file and put the implementation there. (quite a tedious task) | |
But the syntax is not clean however, and quite repetitive too! | |
new Meowable(){ | |
@Override | |
public void meow(){ | |
// THE ACTUALLY IMPORTANT IMPLEMENTATION GOES HERE | |
} | |
} | |
You have to rewrite the outer block of the code above many times if you happen to have different behaviors! | |
We do all that much just to write a single function? Yikes. | |
3. Way 3 | |
So what happen is, in Java 8, they added functional interface that makes this process less verbose. | |
What you can do is to annotate the interface as a @FunctionalInterface, then you can assign | |
the variables holding that interface with a lambda expression. Better yet, the lambda expression | |
doesn't need to hold type because the types are infered from the functional interface | |
*/ | |
meowable = () -> System.out.println("What? I'm not a cat!"); | |
meowable.meow(); | |
/* | |
In the object standpoint, lambda function is just like any other object. | |
Another cool thing about Java 8 is that it allows you to extract behavior which was already in | |
the older JDK using "method reference." | |
*/ | |
Function<Integer, Integer> doubleFunc = Utils::doubleIt; | |
Predicate<Integer> isEven = Utils::trueIfEven; | |
System.out.println(doubleFunc.apply(1)); | |
System.out.println(isEven.test(2)); | |
} | |
public static class Utils{ | |
public static Integer doubleIt(Integer i) { | |
return i*2; | |
} | |
public static boolean trueIfEven(Integer i){ | |
return i % 2 == 0; | |
} | |
} | |
@FunctionalInterface | |
public static interface Meowable{ | |
public void meow(); | |
} | |
public static class SmallMeow implements Meowable{ | |
@Override | |
public void meow(){ | |
System.out.println("meow"); | |
} | |
} | |
public static class LoudMeow implements Meowable{ | |
@Override | |
public void meow(){ | |
System.out.println("MEOOWWWW GRUHHHH!!"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment