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()));