Skip to content

Latest commit

History

46 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

JAVA 8 - Cheat Sheet

Lambda Expression

(inta) -> a * 2; // Calculate the double of aa -> a * 2; // or simply without type
(a, b) -> a + b; // Sum of 2 parameters

If the lambda is more than one expression we can use { } and return

(x, y) -> {
intsum = x + y;
intavg = sum / 2;
returnavg;
}

A lambda expression cannot stand alone in Java, it need to be associated to a functional interface.

interfaceMyMath {
intgetDoubleOf(inta);
}
MyMathd = a -> a * 2; // associated to the interfaced.getDoubleOf(4); // is 8

All examples with "list" use :

List<String> list = [Bohr, Darwin, Galilei, Tesla, Einstein, Newton]

Collections

sortsort(list, comparator)

list.sort((a, b) -> a.length() - b.length())
list.sort(Comparator.comparing(n -> n.length())); // samelist.sort(Comparator.comparing(String::length)); // same//> [Bohr, Tesla, Darwin, Newton, Galilei, Einstein]

removeIf

list.removeIf(w -> w.length() < 6);
//> [Darwin, Galilei, Einstein, Newton]

mergemerge(key, value, remappingFunction)

Map<String, String> names = newHashMap<>();
names.put("Albert", "Ein?");
names.put("Marie", "Curie");
names.put("Max", "Plank");
// Value "Albert" exists// {Marie=Curie, Max=Plank, Albert=Einstein}names.merge("Albert", "stein", (old, val) -> old.substring(0, 3) + val);
// Value "Newname" don't exists// {Marie=Curie, Newname=stein, Max=Plank, Albert=Einstein}names.merge("Newname", "stein", (old, val) -> old.substring(0, 3) + val);

Method Expressions Class::staticMethod

Allows to reference methods (and constructors) without executing them

// Lambda Form:getPrimes(numbers, a -> StaticMethod.isPrime(a));
// Method Reference:getPrimes(numbers, StaticMethod::isPrime);
Method ReferenceLambda Form
StaticMethod::isPrimen -> StaticMethod.isPrime(n)
String::toUpperCase(String w) -> w.toUpperCase()
String::compareTo(String s, String t) -> s.compareTo(t)
System.out::printlnx -> System.out.println(x)
Double::newn -> new Double(n)
String[]::new(int n) -> new String[n]

Streams

Similar to collections, but

  • They don't store their own data
  • The data comes from elsewhere (collection, file, db, web, ...)
  • immutable (produce new streams)
  • lazy (only computes what is necessary !)
// Will compute just 3 "filter"Stream<String> longNames = list
.filter(n -> n.length() > 8)
.limit(3);

Create a new stream

Stream<Integer> stream = Stream.of(1, 2, 3, 5, 7, 11);
Stream<String> stream = Stream.of("Jazz", "Blues", "Rock");
Stream<String> stream = Stream.of(myArray); // or from an arraylist.stream(); // or from a list// Infinit stream [0; inf[Stream<Integer> integers = Stream.iterate(0, n -> n + 1);

Collecting results

// Collect into an array (::new is the constructor reference)String[] myArray = stream.toArray(String[]::new);
// Collect into a List or SetList<String> myList = stream.collect(Collectors.toList());
Set<String> mySet = stream.collect(Collectors.toSet());
// Collect into a StringStringstr = list.collect(Collectors.joining(", "));

mapmap(mapper)
Applying a function to each element

// Apply "toLowerCase" for each elementres = stream.map(w -> w.toLowerCase());
res = stream.map(String::toLowerCase);
//> bohr darwin galilei tesla einstein newtonres = Stream.of(1,2,3,4,5).map(x -> x + 1);
//> 2 3 4 5 6

filterfilter(predicate)
Retains elements that match the predicate

// Filter elements that begin with "E"res = stream.filter(n -> n.substring(0, 1).equals("E"));
//> Einsteinres = Stream.of(1,2,3,4,5).filter(x -> x < 3);
//> 1 2

reduce
Reduce the elements to a single value

Stringreduced = stream
.reduce("", (acc, el) -> acc + "|" + el);
//> |Bohr|Darwin|Galilei|Tesla|Einstein|Newton

limitlimit(maxSize) The n first elements

res = stream.limit(3);
//> Bohr Darwin Galilei

skip Discarding the first n elements

res = strem.skip(2); // skip Bohr and Darwin//> Galilei Tesla Einstein Newton

distinct Remove duplicated elemetns

res = Stream.of(1,0,0,1,0,1).distinct();
//> 1 0

sorted Sort elements (must be Comparable)

res = stream.sorted();
//> Bohr Darwin Einstein Galilei Newton Tesla 

allMatch

// Check if there is a "e" in each elementsbooleanres = words.allMatch(n -> n.contains("e"));

anyMatch: Check if there is a "e" in an element
noneMatch: Check if there is no "e" in elements

parallel Returns an equivalent stream that is parallel

findAny faster than findFirst on parallel streams

Primitive-Type Streams

Wrappers (like Stream) are inefficients. It requires a lot of unboxing and boxing for each element. Better to use IntStream, DoubleStream, etc.

Creation

IntStreamstream = IntStream.of(1, 2, 3, 5, 7);
stream = IntStream.of(myArray); // from an arraystream = IntStream.range(5, 80); // range from 5 to 80Randomgen = newRandom();
IntStreamrand = gen(1, 9); // stream of randoms

Use mapToX (mapToObj, mapToDouble, etc.) if the function yields Object, double, etc. values.

Grouping Results

Collectors.groupingBy

// Groupe by lengthMap<Integer, List<String>> groups = stream
.collect(Collectors.groupingBy(w -> w.length()));
//> 4=[Bohr], 5=[Tesla], 6=[Darwin, Newton], ...

Collectors.toSet

// Same as before but with Set
... Collectors.groupingBy(
w -> w.substring(0, 1), Collectors.toSet()) ...

Collectors.counting Count the number of values in a group

Collectors.summing__summingInt, summingLong, summingDouble to sum group values

Collectors.averaging__averagingInt, averagingLong, ...

// Average length of each element of a groupCollectors.averagingInt(String::length)

PS: Don't forget Optional (like Map<T, Optional<T>>) with some Collection methods (like Collectors.maxBy).

Parallel Streams

Creation

Stream<String> parStream = list.parallelStream();
Stream<String> parStream = Stream.of(myArray).parallel();

unordered Can speed up the limit or distinct

stream.parallelStream().unordered().distinct();

PS: Work with the streams library. Eg. use filter(x -> x.length() < 9) instead of a forEach with an if.

Optional

In Java, it is common to use null to denote absence of result. Problems when no checks: NullPointerException.

// Optional<String> contains a string or nothingOptional<String> res = stream
.filter(w -> w.length() > 10)
.findFirst();
// length of the value or "" if nothingintlength = res.orElse("").length();
// run the lambda if there is a valueres.ifPresent(v -> results.add(v));

Return an Optional

Optional<Double> squareRoot(doublex) {
if (x >= 0) { returnOptional.of(Math.sqrt(x)); }
else { returnOptional.empty(); }
}

Note on inferance limitations

interfacePair<A, B> {
Afirst();
Bsecond();
}

A steam of type Stream<Pair<String, Long>> :

  • stream.sorted(Comparator.comparing(Pair::first)) // ok
  • stream.sorted(Comparator.comparing(Pair::first).thenComparing(Pair::second)) // dont work

Java cannot infer type for the .comparing(Pair::first) part and fallback to Object, on which Pair::first cannot be applied.

The required type for the whole expression cannot be propagated through the method call (.thenComparing) and used to infer type of the first part.

Type must be given explicitly.

stream.sorted(
Comparator.<Pair<String, Long>, String>comparing(Pair::first)
.thenComparing(Pair::second)
) // ok

Exercices et exemples:

// Exercice 1 - Unité 1 //

// Garde les mots plus grand que 20, grâce à la commande removeIf()

publicclassExercise
{
publicstaticvoidmain(String[] args) throwsIOException
{
List<String> words = Files.readAllLines(Paths.get("pays.txt"));
words.removeIf(obj -> obj.length() < 20);
System.out.println(words);
}
} 

// Exercice 2 - Unité 1 //

List<String> words = Files.readAllLines(Paths.get("pays.txt")); // lit notre fichierwords.removeIf(w -> { inttaille = w.length();
Stringfirst = w.substring(0,1);
Stringlast = w.substring(taille-1, taille);
return !first.equalsIgnoreCase(last);
}
);

// Exercice 3 - Unité 1 //

publicclassIndex
{
publicstaticvoidmain(String[] args) throwsIOException
{
Scannerin = newScanner(System.in);
Map<String, String> index = newTreeMap<>();
intline = 0;
while (in.hasNextLine())
{
line++;
for (Stringword : in.nextLine().split("[^'\\pL]+"))
{
//we merge word into a map with the line in first and then//we take the old value and we add to it the new val value//like this we can keep a trace of old value and add new onesindex.merge(word, Integer.toString(line), (old, val)-> old + ", " + val);
}
}
System.out.println(index);
}
}

// Exercice 4 - Unité 1 //

Map<String, Set<Integer>> index = newTreeMap<>();
//nous devons donc faire en sorte que Index soit une Map de String, Set<Integer>index.merge(word, newTreeSet<>(Arrays.asList(line)), (old, next) -> { old.addAll(next);
returnold;
});

// Exercice 1 - Unité 2 //

classWords
{	//static method to access it from the class namepublicstaticintvowels(Stringw)
{
returnw.length() - w.toLowerCase().replaceAll("[aâàäæeéêèëiîïoôœöuûùüyÿ]", "").length();
}
}
publicclassExercise
{
publicstaticvoidmain(String[] args) throwsIOException
{
List<String> words = Files.readAllLines(Paths.get("pays.txt"));
Collections.sort(words, Comparator.comparing(Words::vowels).thenComparing(String::compareTo));
System.out.println(words);
}
}

// Exercice 2 - Unité 2 //

classCollections {
publicstatic <T> T[] toArray(Collection<T> coll, Function<Integer, T[]> constructor)
{
T[] result = constructor.apply(coll.size());
Iterator<T> iter = coll.iterator();
for (inti = 0; i < result.length; i++)
result[i] = iter.next();
returnresult;
}
}
publicclassExercise
{
publicstaticvoidmain(String[] args) throwsIOException
{
List<String> words = Files.readAllLines(Paths.get("pays.txt"));
String[] wordArray = Collections.toArray(words, String[]::new); //create new array of stringsArrays.sort(wordArray);
for (inti = 0; i < 10; i++)
System.out.println(wordArray[i].toUpperCase());
// Note: If wordArray was an Object[], you couldn't call // wordArray[i].toUpperCase().
}
}

// Exercice 3 - Unité 2 //

// TODO: Make this method receive and return an array.// Accept a constructor expression for constructing the // returned array.// Function<T, R> { R apply(T args); }publicclassUtil
{
//First parameter of Function<What apply will take, What apply will return>//La Function prend un int en paramètre et retournera un nouveau tableau de T[]//Here we want apply to take the size of the String[] and to return a new T [] arraypublicstatic <T> T[] filter(T[] values, Predicate<T> p, Function<Integer, T[]> f)
{
List<T> result = newArrayList<>();
for (Tvalue : values)
{
//predicate test value and add it if it's trueif (p.test(value)) { result.add(value); }
}
//on retourne un array de string et on lui passe la taillereturnresult.toArray(f.apply(result.size()));
}
}
//Call of the methodString[] wordsWithA = Util.filter(words, w -> w.contains("a"), String[]::new);
//Way to display an arraySystem.out.println(Arrays.toString(wordsWithA));

// Exercice 1 - Unité 3 //

publicclassWords
{
publicstaticlongdistinctVowels(Stringstr)
{
returnStream.of(str.split("")) //on découpe chaque lettres//on prend un lettre et on lui enlève ses accents //normalize retourne un tableau pour à [a,`]
.map(c -> Normalizer.normalize(c,Normalizer.Form.NFD)
.substring(0,1))
//on filtre notre lettre pour savoir si elle fait partie des//voyelles
.filter(s -> "aeiou".contains(s))
.distinct()	//on prend chaque valeur 1 fois si identique
.count();	//on compte
}
}

// Exercice 2 - Unité 3 //

publicclassStreams
{
publicstaticvoidmain(String[] args) throwsIOException
{
Scannerin = newScanner(System.in);
Stringfilename = in.next();
try (Stream<String> lineStream = Files.lines(Paths.get(filename))){
//Ici on retourne le nombre de mot avec 5 voyelleslongcount = lineStream
.filter(s -> Words.distinctVowels(s) == 5)
.count();
System.out.println(count + " words with 5 distinct vowels"); } try (Stream<String> lineStream = Files.lines(Paths.get(filename))){
//On souhaite récupérer une liste de string depuis le Stream lineStream//on filtre les mots ayant 5 voyelles distinctesList<String> result = lineStream.filter(s -> Words.distinctVowels(s) == 5)
//on trie grace a sorted(Comparator.comparing( Fonction de tri )) //Ici par la longueur (String::length)
.sorted(Comparator.comparing(String::length))
//on limite au 20 premier résultat
.limit(20)
//on collect (Collectors) En toList toArray .. etc
.collect(Collectors.toList());
System.out.println(result);
} }
}

// Exercice 3 - Unité 3 //

publicclassStreams
{
List<Pair<String, Long>> wordsWithManyVowels(Stream<String> words, intn)
{
returnwords
.map(w -> Pair.of(w, (Words.vowels(w) - (w.length() - Words.vowels(w)))))
.sorted(
Comparator.comparingLong((Pair<String,Long> p) -> -p.second())
.thenComparing((Pair<String,Long> p) -> p.first()))
.limit(n)
.collect(Collectors.toList());
}
}

// Collections //

//Exemples avec des collections//opening est une List<String>Collections.max(opening, (s,t) -> s.length() - t.length());
Collections.max(opening,Comparator.comparing(String::length));

// Exemples de Labdas //

//list = (0, 44 , 33) retourne e0,e44,o33publicStringgetString(List<Integer> list) {
returnlist.stream()
.map(n -> n % 2 == 0 ? "e" + n : "o" + n)
//joining retourne une string séparé par ici une virgule
.collect(Collectors.joining(",")); }

// Longest word //

//opening est une liste de string//LambdaCollections.max(opening, (s,t) -> s.length() - t.length());
//CompartorCollections.max(opening,Comparator.comparing(String::length));
//Compartor Streamopening.stream()
.sorted(Comparator.comparing(String::length).reversed())
.findFirst().get();	//get retourne un string

// Filter using predicate greater < 5 //

opening.stream()
.filter(Predicates.greater(String::length,5)) //we pass string.length to func
.distinct()
.toArray(String[]::new);
//L'interface PredicatesinterfacePredicates{ //func will take a T and an Integer//here T is a String and Integer = to the String.length()publicstatic <T> Predicate<T> greater(Function<T,Integer> func, intn){
//so func.apply(p) will return the length of p (a string)//A predicate is a lamba that return true or falsereturnp -> func.apply(p) > n; }
}
System.out.println(Arrays.toString(array));
//----Same without predicates interfacearray = opening.stream().filter(s -> s.length() > 5).distinct().toArray(String[]::new);

// Triangular method - Iterate with interface //

List<Pair<Integer, Integer>> triangles = Streams.triangular(7) //limite a 7
.collect(Collectors.toList());
//we need a method that construct the triangular streaminterfaceStreams{
publicstaticStream<Pair<Integer, Integer>> triangular(intmax){
returnStream.iterate(Pair.of(1,1), //Iterate prend une valeur de départ//en second parametre prend les itérations à faire
(Pair<Integer, Integer> p) -> Pair.of(p.first() + 1, (p.second() -1 ) + p.fist()))
.limit(max);
}
}

// Trier les valeurs pair par nom //

System.out.println(list.stream()
.filter((Pair<String, Integer> p) -> p.second() % 2 == 0)
.sorted(Comparator.comparing(Pair::second))
.map(Pair::first)
.collect(Collectors.toList())
);
System.out.println("-- 5. Sorted even values names");
System.out.println(list.stream()
.filter((Pair<String, Integer> p) -> p.second() % 2 == 0)
.sorted(Comparator.comparing((Pair<String, Integer> p) -> p.second()))
.map((Pair<String,Integer> p) -> p.first())
.collect(Collectors.toList()));

// Trier les valeurs grâce à une interface //

publicclassFilterable{
publicstatic <T> List<T> filter(List<T> mylist, Predicate<T> predicate){
List<T> list = newArrayList<>();
for(Tval: mylist){
if(predicate.test(val)){ list.add(val);}
}
returnlist;
}
}
List<Dragon> oldest = Filterable.filter(dragons, d -> d.color() == Dragon.Color.Red && d.age() >= 4000);

// Summary et Moyennes //

list.stream()
.mapToInt(i -> i) //lambda basique
.average()
.getAsDouble();
collectionKids.stream()
.mapToInt(t -> t.age) //toujours fournir une lambda 
.summaryStatistics() //.getCount() .getMax() .getSum()
.getAverage();

// List vs Maps //

List.
forEach(Iterables)
//ne marche pas sur Array.asList//faire List<String> str2 = new ArrayList<String>(str1);//removeIf mettre l'inverse de ce que l'on souhaiteremoveIf(Collections) replaceAll()
sort()
Map.
forEach()
computeIfAbsent()
merge()
replaceAll()

Predicate & Streams

interfacePredicates{
publicstatic <T> Predicate<T> greater(Function<T, Integer> f, intn) {
returnp -> f.apply(p) > n;
}
}
//Interface Streams mais la méthode retourne un streaminterfaceStreams{
publicstaticStream<Pair<Integer,Integer>> triangular(intmax){
returnStream.iterate(
//Graine (valeur de départ)Pair.of(1,1), //Calcul des valeurs suivantes
(Pair<Integer,Integer> p) -> Pair.of(p.first() + 1, (p.second()-1) + p.first())).limit(max);
}
}

// Accumulator //

//Accumulator sum, lambdaAccumulator.accumulate(list, 0, (r, n) -> r + n.second()));
//on definit un interface et une méthode static accumulate qui prendr une liste de Pair<T, Integer> //un int de départ//une FunctionAcc ou T = Pair<T, Integer> en entree et R (retour) retournera un Integer en sortieinterfaceAccumulator{
publicstatic <T> intaccumulate(List<T> list, intinit, FunctionAcc<T, Integer> f ){
intsum = init;
for (inti = 0; i < list.size(); i++){
sum = f.apply(sum, list.get(i));
}
returnsum;
}
}
interfaceFunctionAcc<T,R>{
//doit être redéfinieRapply(intinit, Targ);
}
// # 1 il faut redéfinir la fonction apply de notre FunctionAcc anonymeintsum = Accumulator.accumulate(list, 0, newFunctionAccumulateur<Pair<String, Integer>, Integer>() {
@OverridepublicIntegerapply(intinit, Pair<String, Integer> arg) {
returninit + arg.second();
}
});
//# 2 ou ecrire notre Function en dehors et la passe a l'accumulatorFunctionAccumulateur<Pair<String, Integer>, Integer> f = newFunctionAccumulateur<Pair<String, Integer>, Integer>() {
@OverridepublicIntegerapply(intinit, Pair<String, Integer> pair) {
returninit + pair.second();
}
};
//Ici on passe notre fonction à l'AccumulatorSystem.out.println(
Accumulator.accumulate(list,0 , f)
);

Interface Filterable

//Sans Compartor, Streams ou Collections retourne les plus vieux DragonspublicclassFilterable
{
publicstatic <T> List<T> filter(List<T> list, Predicate<T>p)
{
// version one-liner, qui ne respecte pas la consigne (pas de Stream ni Collectors)// return list.stream().filter(p).collect(Collectors.toList());// version nettement plus moche, qui respecte la consigne.List<T> copy = newLinkedList<T>();
copy.addAll(list);
copy.removeIf(p.negate()); //on enlève si ca ne respecte pas le predicatereturncopy;
}
}

This cheat sheet was based on the lecture of Cay Horstmann http://horstmann.com/heig-vd/spring2015/poo/

About

JavaStream_CheatSheet

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors