Today, I’m going to show you a little bit of lambda expression in Java 8.
Well, the lambda expression has been added for replace the Anonymous function, sometimes, the anonymous function can be such fat..
an exemple:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("this is an anonymous function");
}
}).start();
with lambda expression:
new Thread(()->System.out.println("this is a lambda expression!")).start();
Lambda expression
the official Grammar is:
(parameters) -> expression
(parameters) ->{ statements; }
there is a couple of exemples
() -> something()
x -> something()
(x,y) -> something()
9 -> {something(); something()}
There is an exemple with Function,
mathematically f.andThen(g) is
or
, f.compose(g) is
of ![]()
/**
* Exemple 1
*/
System.out.println("Exemple1");
//f(x) = 3x+6
Function<Double,Double> f = x -> 3 * x + 6;
//g(x) = 4x^2
Function<Double,Double> g = x -> 4 * Math.pow(x, 2);
//f2(x) = 4(3x+6)^2
Function<Double,Double> f2 = f.andThen(g);
//g2(g) = 3*(4x^2)+6
Function<Double,Double> g2 = f.compose(g);
// 3 * 2 + 6 = 12.0
System.out.println(f.apply(2.0));
// 4 * (2^2) = 16.0
System.out.println(g.apply(2.0));
// 4( 3 * 2 + 6 )^ 2 = 576.0
System.out.println(f2.apply(2.0));
// 3 * (4 * (2^2))+ 6 = 54.0
System.out.println(g2.apply(2.0));
//f3 = f2 = 4(3x+6)^2,
//please look here, the parameter is a function,
Function<Double,Double> f3 = f.andThen(x -> 4 * Math.pow(x, 2));
//576 the same as before f.andThen(g)
System.out.println(f3.apply(2.0));
2nd Exemple with comparator
/**
* Exemple 2
*/
System.out.println("Exemple2");
//a list
List<Integer> list = Arrays.asList(1,4,7,2,5,8,3,6,9,0);
//This is a comparator,
Comparator<Integer> S2B = new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
return o1 -o2;
}};
//of course you can use l.sort() or Collection.sort()
//but as these methods are void, it will change the original order
//so I use stream, it means I create a new list,
//and this list has the same elements as original list, but sorted.
Function<List<Integer>,List<Integer>> sortS2B = l -> l.stream().sorted(S2B).collect(Collectors.toList());
Function<List<Integer>, List<Integer>> sortB2S = l -> l.stream().sorted(S2B.reversed()).collect(Collectors.toList());
//Showing you the list by order increase
System.out.println(sortS2B.apply(list));
//showing you the list by order decrease
System.out.println(sortB2S.apply(list));
//original list:
System.out.println(list);
//or you can just call l.get(0), I'm using stream, because stream is a new part of java 8
//and by using findFirst, it will return an Optional<T> which will showed as
//an Optional<Integer> in my exemple, Optional.orElse(x) means, if this value that in this
//Optional is NOT null, then show you the value, if not, it will show you a "default value"
//,so in my exemple the "default value" is -1
//if you use l.get(0), it will be find in my exemple, but sometimes we have to check the value
//so the statement has to be l -> {if(l.get(0)!= null) return l.get(0); else return -1;};
Function<List<Integer>,Integer> first = l -> l.stream().findFirst().orElse(-1);
//with a empty list, it will show you -1
System.out.println(first.apply(new ArrayList<Integer>()));
//I apply first on the original list 1,4,7,2,5,8,3,6,9,0, so it will show you 1
System.out.println(first.apply(list));
//I apply sortS2B ant then first on the list
//it means sort the list, then find the first
//so it will be 0
System.out.println(sortS2B.andThen(first).apply(list));
//it will find 9
System.out.println(sortB2S.andThen(first).apply(list));
3rd exemple will show you how the sort works with lambda expression
/*
* Exemple 3
*/
System.out.println("Exemple3");
//Now I'll show you the lambda expression...
Function<List<Integer>,List<Integer>> sortS2B2 = l -> l.stream().sorted((x,y) -> x-y).collect(Collectors.toList());
Function<List<Integer>,List<Integer>> sortB2S2 = l -> l.stream().sorted((x,y) -> y-x).collect(Collectors.toList());
//Look the sorted part, the method compare(int x, int y) becomes (x,y) -> x-y,
//compare is a function, so we can pass this function as parameter
System.out.println(sortS2B2.apply(list));
System.out.println(sortB2S2.apply(list));
//sort the list and take the first element
System.out.println(sortS2B2.andThen(l -> l.stream().findFirst().orElse(-1)).apply(list));
System.out.println(sortB2S2.andThen(l -> l.stream().findFirst().orElse(-1)).apply(list));
4th, an ugly exemple
/*
* Exemple 4
*/
System.out.println("Exemple 4");
//I made a list of integer 0 to 199
//IntStream is a stream which makes int
//iterate(0, i -> i+1), from 0 and each element +1
//or you can use IntStream.range(0,200) without limit, I just show you methods as more as possible
//limit(200) I will take only 200,
//boxed() int to integer
//collect() toList
List<Integer> t2t = IntStream.iterate(0, i -> i+1).limit(200).boxed().collect(Collectors.toList());
//look what I've got
System.out.println(t2t);
//Now I'm going to make an ugly function to show you a little bit more
//I made a bifunction which needs two list<Integer> as parameters, and return a String
BiFunction<List<Integer>,List<Integer>,String> int2Char =
//(x,y) means the parameters,
(x,y) -> x.stream()
//new I made a stream from x, the first list
.map(i -> i + y.stream().mapToInt(Integer::intValue).sum())
//each element, in the list x, I made it added the total sum of list y
.map(i -> (char)i.intValue())
//and I made it return the char of this int
.collect(Collectors.toList())
//catch all char in a list
.stream().map(i -> i.toString())
//a stream for chars, and each char become to String
.reduce((acc, e) -> acc + e).get();
//get the string final
//What an ugly exemple, I suppose that you will realize the same thing in you life
//this one just an exemple, I've made it for fun
//show you the final string
System.out.println(int2Char.apply(t2t, list));
reduce
reduce is the most important method, I’d like to give you an exemple:
/**
* Exemple 5
*/
//reduce is fold (also termed reduce, accumulate, aggregate, compress, or inject) refers to
//a family of higher-order functions that analyze a recursive data structure and through use
//of a given combining operation, recombine the results of recursively processing its constituent
//parts, building up a return value.
//via wiki
//Actually, the methods as sum(), max(), min(), they are implementations by using reduce
System.out.println("Exemple5");
System.out.println(IntStream.rangeClosed(1, 10).sum());
System.out.println(IntStream.rangeClosed(1, 10).count());
System.out.println(IntStream.rangeClosed(1, 10).max().orElse(-1));
System.out.println(IntStream.rangeClosed(1, 10).min().orElse(-1));
//reduce has two overloads with IntStream, one is with only one parameter, anther one is with two,
//reduce(operation) or reduce(initValue,operation)
//the only different is the second one has an initial value, some time we have to have one
//
//there is 3rd overload, I'll show you later.
//sum by reduce, if you remove 0, the default value, it will return an optional<Integer>
System.out.println(IntStream.rangeClosed(1, 10).reduce(0, (x,y)-> x+y));
//count by reduce
System.out.println(IntStream.rangeClosed(1, 10).reduce(0, (x,y)-> {return y = ++x;}));
//max by reduce, I set mini value as the default value
System.out.println(IntStream.rangeClosed(1, 10).reduce(Integer.MIN_VALUE, (x,y)-> {return x>y ? x:y;}));
//min by reduce, I didn't set the default value,
System.out.println(IntStream.rangeClosed(1, 10).reduce( (x,y)-> {return x<y ? x:y;}).orElse(-1));
//this is the reduce with 3 parameters,
//this one is a little bit difficult, the other reduces can only return a value which has
//the same value as the input, but this one can return what you want
//just make sure the second parameter and the 3rd have the same type as output
//this exemple is the same functionality as collect(Collectors.toList()),
//it just shows you how the reduce works,
//the initial value is an ArrayList, an empty list of course as the first couple:(list, Integer)
//second parameter is a function which will put the integer into the list, and return the list
//for the next couple,
//3rd parameter, is useless for us, it will work only we use .parallel() as stream().
//so it's why I return an null
//this exemple can be used with paralel(), because of ArrayList, it's not a thread safe collection
System.out.println(IntStream.rangeClosed(1, 10).boxed()
.reduce(new ArrayList<Integer>()
, (List<Integer> x, Integer y) ->
{x.add(y); return x;}
, (List<Integer> x, List<Integer> y) -> {return null;}));
//the same as Above
System.out.println(IntStream.rangeClosed(1, 10).boxed().collect(Collectors.toCollection(ArrayList::new)));
//if you don't care about of which list implementation,
System.out.println(IntStream.rangeClosed(1, 10).boxed().collect(Collectors.toList()));