Saturday, April 1, 2017

Brilliant Java8 tutorial by mkyong

https://www.mkyong.com/tutorials/java-8-tutorials/
I will recap here the salient points.
mkyong analyzes the use of a Functional Interface https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html In a nutshell:
Collections have a sort method using a comparator, which can be a lambda expression (list of named parameters in (params), -> and the method implementation:
List<Developer> listDevs;
listDevs.sort((Developer o1, Developer o2)->o1.getAge()-o2.getAge());


collections have a forEach method, using also a lambda (a Map has a special forEach)
List<Developer> listDevs;
listDevs.forEach((developer)->System.out.println(developer));
listDevs.forEach(System.out::println);

Map<String, Integer> items;
items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));


actually it's not even necessary to declare the type of the parameters, the compiler can infer them from the List type:

listDevs.sort((o1, o2)->o1.getAge()-o2.getAge());


and of course you can assign the Comparator lambda to a variable:
Comparator<Developer> salaryComparator = (o1, o2)->o1.getSalary().compareTo(o2.getSalary());

A Collection can be turned into a stream and filtered
List<String> items;
items.stream().filter(s->s.contains("B")).forEach(System.out::println);


and of course you can turn the result of "stream().filter()" into a Collection using collect():


List<String> result = lines.stream().filter(line -> !"mkyong". equals (line)).collect(Collectors.toList()); 


To return the first match in a filter (and null if not found) there is a compact way:

Person result = persons.stream().filter(x -> "michael".equals(x.getName())).findAny().orElse(null);


You can map on the fly each collection element into a String, using "map()":

String name = persons.stream().filter(x -> "michael".equals(x.getName())).map(Person::getName).findAny().orElse("");


One can also perform "group by" on a Stream, just like in SQL (the syntax is a bit obscure, honestly):

Map<String, Long> result = items.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));


this is well documented here https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html

You can create a stream directly, then convert it to a List:
Stream<String> language = Stream.of("java", "python");
List<String> myList = language.collect(Collectors.toList())


same with an array:
Stream<String> stream1 = Arrays.stream(array);




well, in the long run it becomes quite tedious, all this collection manipulation...

Very cool is the java.util.Optional