SlideShare a Scribd company logo
1 of 177
Download to read offline
@JosePaumard 
nouvelles choses que l’on peut faire avec 
Java
@JosePaumard 
Java 
nouvelles choses que l’on peut faire avec
@JosePaumard 
Java 
nouvelles choses que l’on peut faire avec
@JosePaumard 
#50new8 
Questions ? 
#50new8
Date
@JosePaumard 
#50new8 
Date : Instant 
Un Instant est un point sur une timeline 
Instant start = Instant.now() ; 
Instant end = Instant.now() ;
@JosePaumard 
#50new8 
Date : Duration 
Une « duration » est le temps entre deux Instant 
Instant start = Instant.now() ; 
Instant end = Instant.now() ; 
Duration elapsed = Duration.between(start, end) ; 
long millis = elapsed.toMillis() ;
@JosePaumard 
#50new8 
Date : Duration 
On a une arithmétique sur les « Duration » 
Instant start = Instant.now() ; 
Instant end = Instant.now() ; 
Duration elapsed = Duration.between(start, end) ; 
long millis = elapsed.toMillis() ; 
elapsed.plus(2L, TemporalUnit.SECONDS) ;
@JosePaumard 
#50new8 
Date : Duration 
La précision de la time line est de 10-9 s (nanosecond)
@JosePaumard 
#50new8 
Date : Duration 
La précision de la time line est de 10-9 s (nanosecond) 
Bonne précision ?
@JosePaumard 
#50new8 
Date : Duration 
La précision de la time line est de 10-9 s (nanosecond) 
Bonne précision ? 
La demie-vie du 
boson de Higgs est de 10-23 s
@JosePaumard 
#50new8 
Date : LocalDate 
Une « LocalDate » est une date de tous les jours 
LocalDate now = LocalDate.now() ; 
LocalDate shakespeareDoB = 
LocaleDate.of(1564, Month.APRIL, 23) ;
@JosePaumard 
#50new8 
Date : Period 
Une « Period » est le temps entre deux LocalDate 
LocalDate now = LocalDate.now() ; 
LocalDate shakespeareDoB = 
LocaleDate.of(1564, Month.APRIL, 23) ; 
Period p = shakespeareDoB.until(now) ; 
System.out.println("# years = " + p.getYears()) ;
@JosePaumard 
#50new8 
Date : Period 
Une « Period » est le temps entre deux LocalDate 
LocalDate now = LocalDate.now() ; 
LocalDate shakespeareDoB = 
LocaleDate.of(1564, Month.APRIL, 23) ; 
Period p = shakespeareDoB.until(now) ; 
System.out.println("# years = " + p.getYears()) ; 
long days = shakespeareDoB.until(now, ChronoUnit.DAYS) ; 
System.out.println("# days = " + days) ;
@JosePaumard 
#50new8 
Date : TemporalAdjuster 
On a une arithmétique sur les « local date » 
LocalDate now = LocalDate.now() ; 
LocalDate nextSunday = 
now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
@JosePaumard 
#50new8 
Date : TemporalAdjuster 
On a une arithmétique sur les « local date » 
Une boîte à outils de 14 méthodes statiques 
firstDayOfMonth(), lastDayOfYear() 
firstDayOfNextMonth() 
LocalDate now = LocalDate.now() ; 
LocalDate nextSunday = 
now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
@JosePaumard 
#50new8 
Date : TemporalAdjuster 
On a une arithmétique sur les « local date » 
Une boîte à outils de 14 méthodes statiques 
firstInMonth(DayOfWeek.MONDAY) 
next(DayOfWeek.FRIDAY) 
LocalDate now = LocalDate.now() ; 
LocalDate nextSunday = 
now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
@JosePaumard 
#50new8 
Date : LocalTime 
Un « LocalTime » est un heure de tous les jours : ex. 10:20 
LocalTime now = LocalTime.now() ; 
LocalTime time = LocalTime.of(10, 20) ; // 10:20
@JosePaumard 
#50new8 
Date : LocalTime 
Un « LocalTime » est un heure de tous les jours : ex. 10:20 
LocalTime now = LocalTime.now() ; 
LocalTime time = LocalTime.of(10, 20) ; // 10:20 
LocalTime lunchTime = LocalTime.of(12, 30) ; 
LocalTime coffeeTime = lunchTime.plusHours(2) ; // 14:20
@JosePaumard 
#50new8 
Date : ZonedTime 
Utiles pour les dates localisées 
Set<String> allZonesIds = ZoneId.getAvailableZoneIds() ; 
String ukTZ = ZoneId.of("Europe/London") ;
@JosePaumard 
#50new8 
Date : ZonedTime 
Utiles pour les dates localisées 
System.out.println( 
ZonedDateTime.of( 
1564, Month.APRIL.getValue(), 23, // year / month / day 
10, 0, 0, 0, // h / mn / s / nanos 
ZoneId.of("Europe/London")) 
); // prints 1564-04-23T10:00-00:01:15[Europe/London]
@JosePaumard 
#50new8 
Date : ZonedTime 
On a aussi une arithmétique dessus 
ZonedDateTime currentMeeting = 
ZonedDateTime.of( 
LocalDate.of(2014, Month.APRIL, 18), // LocalDate 
LocalTime.of(9, 30), // LocalTime 
ZoneId.of("Europe/London") 
); 
ZonedDateTime nextMeeting = 
currentMeeting.plus(Period.ofMonth(1));
@JosePaumard 
#50new8 
Date : ZonedTime 
On a aussi une arithmétique dessus 
ZonedDateTime currentMeeting = 
ZonedDateTime.of( 
LocalDate.of(2014, Month.APRIL, 18), // LocalDate 
LocalTime.of(9, 30), // LocalTime 
ZoneId.of("Europe/London") 
); 
ZonedDateTime nextMeeting = 
currentMeeting.plus(Period.ofMonth(1)) ; 
ZonedDateTime nextMeetingUS = 
nextMeeting.withZoneSameInstant(ZoneId.of("US/Central")) ;
@JosePaumard 
#50new8 
Date : Formatter 
Classe factory : DateTimeFormatter 
ZonedDateTime nextMeetingUS = 
nextMeeting.withZoneSameInstant(ZoneId.of("US/Central")); 
System.out.println( 
DateTimeFormatter.ISO_DATE_TIME.format(nextMeetingUS) 
); 
// prints 2014-04-12T03:30:00-05:00[US/Central] 
System.out.println( 
DateTimeFormatter.RFC_1123_DATE_TIME.format(nextMeetingUS) 
); 
// prints Sat, 12 Apr 2014 03:30:00 -0500
@JosePaumard 
#50new8 
Date : liens avec java.util.Date 
Date & Time API vs java.util.Date 
Date date = Date.from(instant); // API -> legacy 
Instant instant = date.toInstant(); // legacy -> new API
@JosePaumard 
#50new8 
Date : liens avec java.util.Date 
Date & Time API vs java.util.Date 
TimeStamp time = TimeStamp.from(instant); // API -> legacy 
Instant instant = time.toInstant(); // legacy -> new API 
Date date = Date.from(instant); // API -> legacy 
Instant instant = date.toInstant(); // legacy -> new API
@JosePaumard 
#50new8 
Date : liens avec java.util.Date 
Date & Time API vs java.util.Date 
Date date = Date.from(localDate); // API -> legacy 
LocalDate localDate = date.toLocalDate(); // legacy -> new API 
TimeStamp time = TimeStamp.from(instant); // API -> legacy 
Instant instant = time.toInstant(); // legacy -> new API 
Date date = Date.from(instant); // API -> legacy 
Instant instant = date.toInstant(); // legacy -> new API
@JosePaumard 
#50new8 
Date : liens avec java.util.Date 
Date & Time API vs java.util.Date 
Time time = Time.from(localTime); // API -> legacy 
LocalTime localTime = time.toLocalTime(); // legacy -> new API 
Date date = Date.from(localDate); // API -> legacy 
LocalDate localDate = date.toLocalDate(); // legacy -> new API 
TimeStamp time = TimeStamp.from(instant); // API -> legacy 
Instant instant = time.toInstant(); // legacy -> new API 
Date date = Date.from(instant); // API -> legacy 
Instant instant = date.toInstant(); // legacy -> new API
String
@JosePaumard 
#50new8 
String : Stream 
Un Stream sur les lettres qui composent une String 
String s = "hello"; 
IntStream stream = s.chars(); // stream on the letters of s
@JosePaumard 
#50new8 
String : Stream 
Un Stream sur les lettres qui composent une String 
String s = "hello"; 
IntStream stream = s.chars(); // stream on the letters of s 
s.chars() 
.map(Character::toUpperCase) 
.forEach(System.out::println);
@JosePaumard 
#50new8 
String : Stream 
Un Stream sur les lettres qui composent une String 
String s = "hello"; 
IntStream stream = s.chars(); // stream on the letters of s 
s.chars() 
.map(Character::toUpperCase) 
.forEach(System.out::println); 
> 
HELLO 
7269767679
@JosePaumard 
#50new8 
String : Stream 
Un Stream sur les lettres qui composent une String 
String s = "hello"; 
IntStream stream = s.chars(); // stream on the letters of s 
s.chars() // IntStream 
.map(Character::toUpperCase) 
.forEach(System.out::println); // Prints an int! 
> 
7269767679
@JosePaumard 
#50new8 
String : Stream 
Un Stream sur les lettres qui composent une String 
String s = "hello"; 
IntStream stream = s.chars(); // stream on the letters of s 
s.chars() // IntStream 
.mapToObj(letter -> (char)letter) // Stream<Character> 
.map(Character::toUpperCase) 
.forEach(System.out::println); // Prints a Character 
> 
HELLO
@JosePaumard 
#50new8 
String : expressions régulières 
Un Stream sur une expression régulière 
// book is a looooooooong String 
Stream<String> words = 
Pattern 
.compile("[^p{javaLetter}]") 
.splitAsStream(book) ;
@JosePaumard 
#50new8 
String : concaténation 
Le débutant écrit : 
String s1 = "hello" ; 
String s2 = " world!" ; 
String s3 = s1 + " " + s2 ;
@JosePaumard 
#50new8 
String : concaténation 
L’ignorant lui dit d’écrire : 
StringBuffer sb1 = new StringBuffer("hello") ; 
sb1.append(" world") ; 
String s3 = sb1.toString() ; 
(et il a tord)
@JosePaumard 
#50new8 
String : concaténation 
Le développeur expérimenté lui dit d’écrire : 
StringBuilder sb1 = new StringBuilder("hello") ; 
sb1.append(" world") ; 
String s3 = sb1.toString() ; 
(et il se trompe aussi…)
@JosePaumard 
#50new8 
String : concaténation 
Parce que le débutant a raison (même s’il ne le sait pas) 
String s1 = "hello" ; 
String s2 = " world!" ; 
String s3 = s1 + " " + s2 ; 
LINENUMBER 10 L2 
NEW java/lang/StringBuilder 
DUP 
ALOAD 1 
INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String; 
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V 
LDC " " 
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder; 
ALOAD 2 
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder; 
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String; 
ASTORE 3
@JosePaumard 
#50new8 
String : concaténation 
L’expert Java 8 écrit : 
// The JDK 8 way 
StringJoiner sj = new StringJoiner(", ") ; 
sj.add("one").add("two").add("three") ; 
String s = sj.toString() ; 
System.out.println(s) ;
@JosePaumard 
#50new8 
String : concaténation 
L’expert Java 8 écrit : 
Ce qui écrit : 
// The JDK 8 way 
StringJoiner sj = new StringJoiner(", ") ; 
sj.add("one").add("two").add("three") ; 
String s = sj.toString() ; 
System.out.println(s) ; 
> one, two, three
@JosePaumard 
#50new8 
String : concaténation 
L’expert Java 8 écrit : 
Ce qui écrit : 
// The JDK 8 way 
StringJoiner sj = new StringJoiner(", ") ; 
sj.add("one") ; 
String s = sj.toString() ; 
System.out.println(s) ; 
> one
@JosePaumard 
#50new8 
String : concaténation 
L’expert Java 8 écrit : 
Ce qui écrit : 
// The JDK 8 way 
StringJoiner sj = new StringJoiner(", ", "{", "}") ; 
sj.add("one").add("two").add("three") ; 
String s = sj.toString() ; 
System.out.println(s) ; 
> {one, two, three}
@JosePaumard 
#50new8 
String : concaténation 
L’expert Java 8 écrit : 
Ce qui écrit : 
// The JDK 8 way 
StringJoiner sj = new StringJoiner(", ", "{", "}") ; 
sj.add("one") ; 
String s = sj.toString() ; 
System.out.println(s) ; 
> {one}
@JosePaumard 
#50new8 
String : concaténation 
L’expert Java 8 écrit : 
Ce qui écrit : 
// The JDK 8 way 
StringJoiner sj = new StringJoiner(", ", "{", "}") ; 
// we dont put anything in it 
String s = sj.toString() ; 
System.out.println(s) ; 
> {}
@JosePaumard 
#50new8 
String : concaténation 
Et on peut presque le faire de la classe String : 
Ce qui écrit : 
// From the String class, with a vararg 
String s = String.join(", ", "one", "two", "three"); 
System.out.println(s); 
> one, two, three
@JosePaumard 
#50new8 
String : concaténation 
Et on peut presque le faire de la classe String : 
Ce qui écrit : 
// From the String class, with an Iterable 
String [] tab = {"one", "two", "three"} ; 
String s = String.join(", ", tab) ; 
System.out.println(s) ; 
> one, two, three
Numbers
@JosePaumard 
#50new8 
Nombres : nouvelles méthodes 
Méthodes max, min, sum 
// max method available on number wrapper classes 
long max = Long.max(1L, 2L); 
long sum = Long.sum(1L, 2L);
@JosePaumard 
#50new8 
Nombres : nouvelles méthodes 
Méthodes max, min, sum 
Si utile que ça ? 
// max method available on number wrapper classes 
long max = Long.max(1L, 2L); 
long sum = Long.sum(1L, 2L);
@JosePaumard 
#50new8 
Nombres : nouvelles méthodes 
Méthodes max, min, sum 
Si utile que ça ? 
// max method available on number wrapper classes 
long max = Long.max(1L, 2L); 
long sum = Long.sum(1L, 2L); 
persons.stream() 
.map(Person::getAge) 
.reduce(0, (a1, a2) -> Integer.max(a1, a2));
@JosePaumard 
#50new8 
Nombres : nouvelles méthodes 
Méthodes max, min, sum 
Si utile que ça ? Utile pour écrire des method references 
// max method available on number wrapper classes 
long max = Long.max(1L, 2L); 
long sum = Long.sum(1L, 2L); 
persons.stream() 
.map(Person::getAge) 
.reduce(0, Integer::max);
@JosePaumard 
#50new8 
Nombres : nouvelles méthodes 
Méthodes max, min, sum 
// max method available on number wrapper classes 
long max = Long.max(1L, 2L); 
long sum = Long.sum(1L, 2L); 
persons.stream() 
.mapToInt(Person::getAge) 
.max();
@JosePaumard 
#50new8 
Nombres : nouvelles méthodes 
Méthodes max, min, sum 
// max method available on number wrapper classes 
long max = Long.max(1L, 2L); 
long sum = Long.sum(1L, 2L); 
persons.stream() 
.max(Comparator.comparingBy(Person::getAge));
@JosePaumard 
#50new8 
Nombres : nouvelles méthodes 
Calcul de code du hachage 
// JDK 7 
long l = 3141592653589793238L; 
int hash = new Long(l).hashCode(); // -1985256439
@JosePaumard 
#50new8 
Nombres : nouvelles méthodes 
Calcul de code du hachage 
// JDK 7 
long l = 3141592653589793238L; 
int hash = new Long(l).hashCode(); // -1985256439 
// JDK 8 
long l = 3141592653589793238L; 
int hash = Long.hashCode(l); // -1985256439
I/O
@JosePaumard 
#50new8 
I/O : lecture de fichiers texte 
Stream étend AutoCloseable 
// Java 7 : try with resources and use of Paths 
Path path = Paths.get("d:", "tmp", "debug.log"); 
try (Stream<String> stream = Files.lines(path)) { 
stream.filter(line -> line.contains("ERROR")) 
.findFirst() 
.ifPresent(System.out::println); 
} catch (IOException ioe) { 
// handle the exception 
}
@JosePaumard 
#50new8 
I/O : lecture de fichiers texte 
Files.list retourne le contenu d’un répertoire 
// Java 7 : try with resources and use of Paths 
Path path = Paths.get("c:", "windows"); 
try (Stream<Path> stream = Files.list(path)) { 
stream.filter(path -> path.toFile().isDirectory()) 
.forEach(System.out::println); 
} catch (IOException ioe) { 
// handle the exception 
}
@JosePaumard 
#50new8 
I/O : lecture d’une arborescence 
Files.walk retourne le contenu d’un répertoire 
// Java 7 : try with resources and use of Paths 
Path path = Paths.get("c:", "windows"); 
try (Stream<Path> stream = Files.walk(path)) { 
stream.filter(path -> path.toFile().isDirectory()) 
.forEach(System.out::println); 
} catch (IOException ioe) { 
// handle the exception 
}
@JosePaumard 
#50new8 
I/O : lecture d’une arborescence 
Files.walk peut limiter la profondeur d’exploration 
// Java 7 : try with resources and use of Paths 
Path path = Paths.get("c:", "windows"); 
try (Stream<Path> stream = Files.walk(path, 2)) { 
stream.filter(path -> path.toFile().isDirectory()) 
.forEach(System.out::println); 
} catch (IOException ioe) { 
// handle the exception 
}
List
@JosePaumard 
#50new8 
Iterable : forEach 
ForEach : permet de consommer les éléments 
Dommage : pas sur les tableaux 
// method forEach defined on Iterable 
List<String> strings = 
Arrays.asList("one", "two", "three") ; 
strings.forEach(System.out::println) ; 
> one, two, three
@JosePaumard 
#50new8 
Collection : removeIf 
Retire un objet à partir d’un prédicat 
Collection<String> strings = 
Arrays.asList("one", "two", "three", "four"); 
// works « in place », no Collections.unmodifiable... 
Collection<String> list = new ArrayList<>(strings); 
// returns true if the list has been modified 
boolean b = list.removeIf(s -> s.length() > 4); 
> one, two, four
@JosePaumard 
#50new8 
List : replaceAll 
Remplace un objet par sa transformation 
List<String> strings = 
Arrays.asList("one", "two", "three", "four"); 
// works « in place », no Collections.unmodifiable... 
List<String> list = new ArrayList<>(strings); 
// returns nothing 
list.replaceAll(String::toUpperCase); 
> ONE, TWO, THREE, FOUR
@JosePaumard 
#50new8 
List : sort 
Trie une liste « en place », à l’aide d’un Comparator 
List<String> strings = 
Arrays.asList("one", "two", "three", "four"); 
// works « in place », no Collections.unmodifiable... 
List<String> list = new ArrayList<>(strings); 
// returns nothing 
list.sort(Comparator.naturalOrder()) ; 
> four, one, three, two
Comparator
@JosePaumard 
#50new8 
Comparator ! 
Que dire de mieux ? 
Comparator.naturalOrder() ;
@JosePaumard 
#50new8 
Comparator ! 
Que dire de mieux ? 
Comparator.naturalOrder() 
public static 
<T extends Comparable<? super T>> Comparator<T> naturalOrder() { 
return (Comparator<T>) 
Comparators.NaturalOrderComparator.INSTANCE; 
}
@JosePaumard 
#50new8 
Comparator ! 
enum NaturalOrderComparator 
implements Comparator<Comparable<Object>> { 
INSTANCE; // What is this??? 
}
@JosePaumard 
#50new8 
Comparator ! 
enum NaturalOrderComparator 
implements Comparator<Comparable<Object>> { 
INSTANCE; // OMG: a SINGLETON!!! 
} 
public class MySingleton { 
INSTANCE; 
private MySingleton() {} 
public static MySingleton getInstance() { 
// some buggy double-checked locking code 
return INSTANCE; 
} 
}
@JosePaumard 
#50new8 
Comparator ! 
enum NaturalOrderComparator 
implements Comparator<Comparable<Object>> { 
INSTANCE; 
public int compare(Comparable<Object> c1, Comparable<Object> c2) { 
return c1.compareTo(c2); 
} 
}
@JosePaumard 
#50new8 
Comparator ! 
enum NaturalOrderComparator 
implements Comparator<Comparable<Object>> { 
INSTANCE; 
public int compare(Comparable<Object> c1, Comparable<Object> c2) { 
return c1.compareTo(c2); 
} 
public Comparator<Comparable<Object>> reversed() { 
return Comparator.reverseOrder(); 
} 
}
@JosePaumard 
#50new8 
À l’ancienne ! 
Comparator ! 
// comparison using the last name 
Comparator<Person> compareLastName = 
new Comparator<Person>() { 
@Override 
public int compare(Person p1, Person p2) { 
return p1.getLastName().compareTo(p2.getLastName()); 
} 
};
@JosePaumard 
#50new8 
Comparator ! 
// comparison using the last name then the first name 
Comparator<Person> compareLastNameThenFirstName = 
new Comparator<Person>() { 
@Override 
public int compare(Person p1, Person p2) { 
int lastNameComparison = 
p1.getLastName().compareTo(p2.getLastName()); 
return lastNameComparison == 0 ? 
p2.getFirstName().compareTo(p2.getFirstName()); 
lastNameComparison; 
} 
};
@JosePaumard 
#50new8 
Comparator ! 
À la façon du JDK 8 ! 
Comparator.comparingBy(Person::getLastName); // static method
@JosePaumard 
#50new8 
Comparator ! 
À la façon du JDK 8 ! 
Comparator.comparingBy(Person::getLastName) // static method 
.thenComparing(Person::getFirstName); // default method
@JosePaumard 
#50new8 
Comparator ! 
À la façon du JDK 8 ! 
Comparator.comparingBy(Person::getLastName) // static method 
.thenComparing(Person::getFirstName) // default method 
.thenComparing(Person::getAge);
@JosePaumard 
#50new8 
Comparator ! 
Vous n’aimez pas l’ordre naturel ? 
Comparator<Person> comp = Comparator.naturalOrder(); 
Comparator<Person> reversedComp = Comparator.reversedOrder();
@JosePaumard 
#50new8 
Comparator ! 
Vous n’aimez pas l’ordre naturel ? 
Comparator<Person> comp = Comparator.comparingBy(Person::getLastName); 
Comparator<Person> reversedComp = comp.reversed();
@JosePaumard 
#50new8 
Comparator ! 
Et que fait-on pour les valeurs nulles ? 
Comparator<Person> comp = 
Comparator.naturalOrder();
@JosePaumard 
#50new8 
Comparator ! 
Et que fait-on pour les valeurs nulles ? 
Comparator<Person> comp = 
Comparator.nullsFirst(Comparator.naturalOrder());
@JosePaumard 
#50new8 
Comparator ! 
Et que fait-on pour les valeurs nulles ? 
Comparator<Person> comp = 
Comparator.nullsFirst(Comparator.naturalOrder()); 
Comparator<Person> comp = 
Comparator.nullsLast(Comparator.naturalOrder());
Optional
@JosePaumard 
#50new8 
Optional 
Optional a été créé pour indiquer qu’une méthode peut ne retourner « aucune valeur » 
Ex : max(), min()
@JosePaumard 
#50new8 
Optional 
Optional a été créé pour indiquer qu’une méthode peut ne retourner « aucune valeur » 
Ex : max(), min(), average()
@JosePaumard 
#50new8 
Optional 
Un Optional est un type enveloppe, qui peut être vide 
Comment peut-on en créer un ? 
Optional<String> opt = Optional.<String>empty() ; 
Optional<String> opt = Optional.of("one") ; // not null 
Optional<String> opt = Optional.ofNullable(s) ; // may be null
@JosePaumard 
#50new8 
Optional 
Un Optional est un type enveloppe, qui peut être vide 
Comment peut-on en créer un ? 
Optional<String> opt = ... ; 
if (opt.isPresent()) { 
String s = opt.get() ; 
} else { 
... 
}
@JosePaumard 
#50new8 
Optional 
Un Optional est un type enveloppe, qui peut être vide 
Comment peut-on en créer un ? 
String s = opt.orElse("") ; // this is a default value that 
// is valid for our application 
Optional<String> opt = ... ; 
if (opt.isPresent()) { 
String s = opt.get() ; 
} else { 
... 
}
@JosePaumard 
#50new8 
Optional 
Un Optional est un type enveloppe, qui peut être vide 
Comment peut-on en créer un ? 
String s = opt.orElseThrow(MyException::new) ; // lazy initialization
@JosePaumard 
#50new8 
Optional : patterns 
Un Optional peut aussi être vu comme un Stream 
comportant 0 ou 1 élément 
void ifPresent(Consumer<T> consumer) ;
@JosePaumard 
#50new8 
Optional : patterns 
Un Optional peut aussi être vu comme un Stream 
comportant 0 ou 1 élément 
void ifPresent(Consumer<T> consumer) ; 
Optional<T> filter(Predicate<T> mapper) ;
@JosePaumard 
#50new8 
Optional : patterns 
Un Optional peut aussi être vu comme un Stream 
comportant 0 ou 1 élément 
void ifPresent(Consumer<T> consumer) ; 
Optional<T> filter(Predicate<T> mapper) ; 
Optional<U> map(Function<T, U> mapper) ;
@JosePaumard 
#50new8 
Optional : patterns 
Un Optional peut aussi être vu comme un Stream 
comportant 0 ou 1 élément 
void ifPresent(Consumer<T> consumer) ; 
Optional<T> filter(Predicate<T> mapper) ; 
Optional<U> map(Function<T, U> mapper) ; 
Optional<U> flatMap(Function<T, Optional<U>> mapper) ;
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
public class NewMath { 
public static Optional<Double> inv(Double d) { 
return d == 0.0d ? Optional.empty() : 
Optional.of(1/d) ; 
} 
public static Optional<Double> sqrt(Double d) { 
return d < 0.0d ? Optional.empty() : 
Optional.of(Math.sqrt(d)) ; 
} 
}
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; 
List<Double> result = new ArrayList<>() ; 
doubles.forEach( 
d1 -> NewMath.inv(d1) // Optional<Double> 
.flatMap(d2 -> NewMath.sqrt(d2)) // Optional<Double> 
.ifPresent(result::add) 
) ; 
doubles : [-1.0, 0.0, 1.0] 
result : [1.0]
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; 
List<Double> result = new ArrayList<>() ; 
doubles.forEach( 
d1 -> NewMath.inv(d1) // Optional<Double> 
.flatMap(d2 -> NewMath.sqrt(d2)) // Optional<Double> 
.ifPresent(result::add) // Baaaaad pattern  
) ; 
doubles : [-1.0, 0.0, 1.0] 
result : [1.0]
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; 
List<Double> result = new ArrayList<>() ; 
doubles.forEach( 
d1 -> NewMath.inv(d1) // Optional<Double> 
.flatMap(d2 -> NewMath.sqrt(d2)) // Optional<Double> 
.ifPresent(result::add) // Baaaaad pattern  
) ; 
doubles : [-1.0, 0.0, 1.0] 
result : [1.0]
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
Function<Double, Optional<Double>> f = 
d -> NewMath.inv(d) // Optional<Double> 
.flatMap(d -> NewMath.sqrt(d))// Optional<Double>
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
d -> NewMath.inv(d) // Optional<Double> 
.flatMap(NewMath::sqrt) // Optional<Double> 
.map(Stream::of) // Optional<Stream<Double>>
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
d -> NewMath.inv(d) // Optional<Double> 
.flatMap(NewMath::sqrt) // Optional<Double> 
.map(Stream::of) // Optional<Stream<Double>> 
.orElse(Stream.empty()) // Stream<Double>
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
Function<Double, Stream<Double>> f = 
d -> NewMath.inv(d) // Optional<Double> 
.flatMap(NewMath::sqrt) // Optional<Double> 
.map(Stream::of) // Optional<Stream<Double>> 
.orElse(Stream.empty()) ; // Stream<Double>
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; 
doubles.stream() 
.flatMap( 
d -> NewMath.inv(d) // Optional<Double> 
.flatMap(NewMath::sqrt) // Optional<Double> 
.map(Stream::of) // Optional<Stream<Double>> 
.orElse(Stream.empty()) // Stream<Double> 
) // Stream<Double>
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; 
List<Double> result = 
doubles.stream() 
.flatMap( 
d -> NewMath.inv(d) // Optional<Double> 
.flatMap(NewMath::sqrt) // Optional<Double> 
.map(Stream::of) // Optional<Stream<Double>> 
.orElse(Stream.empty()) // Stream<Double> 
) // Stream<Double> 
.collect(Collectors.toList()) ;
@JosePaumard 
#50new8 
Optional : nouveaux patterns en vue ! 
List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; 
List<Double> result = 
doubles.stream().parallel() 
.flatMap( 
d -> NewMath.inv(d) // Optional<Double> 
.flatMap(NewMath::sqrt) // Optional<Double> 
.map(Stream::of) // Optional<Stream<Double>> 
.orElse(Stream.empty()) // Stream<Double> 
) // Stream<Double> 
.collect(Collectors.toList()) ;
Map
@JosePaumard 
#50new8 
Map : forEach 
Prend un BiConsumer 
// the existing map 
Map<String, Person> map = ... ; 
map.forEach( 
(key, value) -> System.out.println(key + " -> " + value) 
) ;
@JosePaumard 
#50new8 
Map : get 
Que se passe-t-il si la clé n’est pas dans la map ? 
// the existing map 
Map<String, Person> map = ... ; 
Person p = map.get(key);
@JosePaumard 
#50new8 
Map : get 
On peut retourner une valeur par défaut 
// the existing map 
Map<String, Person> map = ... ; 
Person p = map.getOrDefault(key, Person.DEFAULT_PERSON);
@JosePaumard 
#50new8 
Map : put 
Même idée pour le put 
// the existing map 
Map<String, Person> map = ... ; 
map.put(key, person);
@JosePaumard 
#50new8 
Map : putIfAbsent 
Même idée pour le put 
// the existing map 
Map<String, Person> map = ... ; 
map.put(key, person); 
map.putIfAbsent(key, person);
@JosePaumard 
#50new8 
Map : replace 
Même idée pour le replace 
// the existing map 
Map<String, Person> map = ... ; 
// key, newValue 
map.replace("six", john) ; 
// key, oldValue, newValue 
map.replace("six", peter, john) ;
@JosePaumard 
#50new8 
Map : replaceAll 
Permet de « remapper » une map avec une l 
// the existing map 
Map<String, Person> map = ... ; 
// key, oldValue 
map.replaceAll( 
(key, value) -> key + " -> " + value ; 
) ;
@JosePaumard 
#50new8 
Map : remove 
Efface une paire clé / valeur si elle est la 
// the existing map 
Map<String, Person> map = ... ; 
// key, oldValue 
map.remove("six", john) ;
@JosePaumard 
#50new8 
Map : compute 
Calcule une valeur à partir d’une paire clé / valeur existante, et d’une l 
// the existing map 
Map<String, Person> map = ... ; 
// key, oldValue 
map.compute( 
key, 
(key, person) -> key + "::" + person // person can be null 
) ;
@JosePaumard 
#50new8 
Map : computeIfAbsent 
Calcule une valeur à partir d’une clé si elle n’est pas dans la map 
// the existing map 
Map<String, Person> map = ... ; 
// key, no existing value 
map.computeIfAbsent( 
key, 
key -> person 
) ;
@JosePaumard 
#50new8 
Map : computeIfPresent 
Calcule une valeur à partir d’une paire clé / valeur présente, et d’une l 
// the existing map 
Map<String, Person> map = ... ; 
// key, the existing value 
map.computeIfPresent( 
key, person, 
(key, person) -> newPerson // person cannot be null 
) ;
@JosePaumard 
#50new8 
Map : compute* 
Le truc, c’est que ces méthodes retournent la valeur, qu’elle ait été juste créée ou pas
@JosePaumard 
#50new8 
Construire des maps de maps 
Construire des maps de maps devient un jeu d’enfant ! 
// the existing map 
Map<String, Map<String, Person>> map = ... ; 
// key, newValue 
map.computeIfAbsent( 
"one", 
(key) -> HashMap::new 
).put("two", john);
@JosePaumard 
#50new8 
Map : merge 
Calcule une nouvelle valeur à partir de la paire clé / valeur existante, d’une valeur à ajouter, et d’une l 
// the existing map 
Map<Long, String> map = ... ; 
// key, otherValue 
map.merge( 
key, 
otherValue, 
(value, otherValue) -> String.join(", ", value, otherValue) 
) ;
Annotations
@JosePaumard 
#50new8 
Annotations en Java 7 
Une annotation ne peut être posée qu’une fois 
Donc on crée des annotations enveloppe… 
@TestCases({ 
@TestCase(param=1, expected=false), 
@TestCase(param=2, expected=true) 
}) 
public boolean even(int param) { 
return param % 2 == 0; 
}
@JosePaumard 
#50new8 
Annotations en Java 8 
Avec Java 8, on peut ! 
@TestCase(param=1, expected=false), 
@TestCase(param=2, expected=true) 
public boolean even(int param) { 
return param % 2 == 0; 
}
@JosePaumard 
#50new8 
Comment ça marche ? 
En fait, il y a un truc !
@JosePaumard 
#50new8 
Comment ça marche ? 
D’abord, on crée nos annotations comme avant 
@interface TestCase { 
int param(); 
boolean expected(); 
} 
@interface TestCases { 
TestCase[] value(); 
}
@JosePaumard 
#50new8 
Comment ça marche ? 
Et on ajoute @Repeatable 
@Repeatable(TestCases.class) 
@interface TestCase { 
int param(); 
boolean expected(); 
} 
@interface TestCases { 
TestCase[] value(); 
}
@JosePaumard 
#50new8 
Type annotations 
Les annotations peuvent être posées sur les types 
Exemple 1 : nous dit que persons ne peut pas être nul 
private @NonNull List<Person> persons = ... ;
@JosePaumard 
#50new8 
Type annotations 
Les annotations peuvent être posées sur les types 
Exemple 1 : nous dit que persons ne peut pas être nul 
Exemple 2 : la liste ne peut contenir des valeurs nulles 
private @NonNull List<Person> persons = ... ; 
private @NonNull List<@NonNull Person> persons = ... ;
Arrays 
Parallel
@JosePaumard 
#50new8 
Parallel Arrays 
Arrays.parallelSetAll 
long [] array = new long [...] ; 
Arrays.parallelSetAll(array, index -> index % 3) ; 
System.out.println(Arrays.toString(array)) ;
@JosePaumard 
#50new8 
Parallel Arrays 
Arrays.parallelPrefix : fold right 
long [] array = new long [...] ; 
Arrays.parallelPrefix(array, (l1, l2) -> l1 + l2) ; 
System.out.println(Arrays.toString(array)) ; 
long [] array = {1L, 1L, 1L, 1L} ; 
> [1, 2, 3, 4]
@JosePaumard 
#50new8 
Parallel Arrays 
Arrays.parallelSort : tri « en place » 
long [] array = new long [...] ; 
Arrays.parallelSort(array) ; 
System.out.println(Arrays.toString(array)) ;
Completable 
Future
@JosePaumard 
#50new8 
CompletableFuture 
Implémente Future 
CompletableFuture<String> page = 
CompletableFuture.supplyAsync( 
) ;
@JosePaumard 
#50new8 
CompletableFuture 
Implémente Future 
CompletableFuture<String> page = 
CompletableFuture.supplyAsync( 
() -> 
readWebPage(url) // returns String 
) ;
@JosePaumard 
#50new8 
CompletableFuture 
On peut alors créer des pipelines 
CompletableFuture.supplyAsync( 
() -> 
readWebPage(url) 
) 
.thenApply( 
content -> getImages(content) // returns a List<Image> 
) ; // returns a CompletableFuture<List<Image>>
@JosePaumard 
#50new8 
CompletableFuture 
On peut alors créer des pipelines 
CompletableFuture.supplyAsync( 
() -> 
readWebPage(url) 
) 
.thenApply( 
content -> getImages(content) // returns a List<Image> 
) 
.thenAccept( 
images -> images.forEach(System.out::println) 
);
@JosePaumard 
#50new8 
CompletableFuture 
thenCompose() : permet de composer les choses 
CompletableFuture.supplyAsync( 
() -> 
readWebPage(url) 
) 
.thenCompose( 
content -> getImages(content) // returns List<Image> 
)
@JosePaumard 
#50new8 
CompletableFuture 
allOf : termine quand tout les calculs sont faits (anyOf) 
CompletableFuture.allOf( 
CompletableFuture.supplyAsync( 
() -> 
readWebPage(url) 
) 
.thenCompose(content -> getImages(content)) 
.thenApply(image -> writeToDisk(image)) 
) 
.join() ;
@JosePaumard 
#50new8 
CompletableFuture 
thenCombine : combine plusieurs CF avec une l 
La l est appliquée au résultat des deux CF 
CompletableFuture cf1 = ... ; 
CompletableFuture cf2 = ... ; 
cf1.thenCombine(cf2, (b1, b2) -> b1 & b2) ; // can combine 
// the results of CFs
@JosePaumard 
#50new8 
CompletableFuture 
thenCombine : combine plusieurs CF avec une l 
La l est appliquée au résultat des deux CF 
On a aussi : thenAcceptBoth, runAfterBoth 
CompletableFuture cf1 = ... ; 
CompletableFuture cf2 = ... ; 
cf1.thenCombine(cf2, (b1, b2) -> b1 & b2) ; // can combine 
// the results of CFs
@JosePaumard 
#50new8 
CompletableFuture 
applyToEither : prend le premier résultat disponible 
CompletableFuture cf1 = ... ; 
CompletableFuture cf2 = ... ; 
cf1.applyToEither(cf2, (b) -> ...) ; // applies to the first 
// CF that returns
@JosePaumard 
#50new8 
CompletableFuture 
applyToEither : prend le premier résultat disponible 
acceptEither, runAfterEither 
CompletableFuture cf1 = ... ; 
CompletableFuture cf2 = ... ; 
cf1.applyToEither(cf2, (b) -> ...) ; // applies to the first 
// CF that returns
Concurrence
@JosePaumard 
#50new8 
Variables atomiques 
Java 5 : 
AtomicLong atomic = new AtomicLong() ; 
long l1 = atomic.incrementAndGet() ;
@JosePaumard 
#50new8 
Variables atomiques 
Java 8 nous amène : 
AtomicLong atomic = new AtomicLong() ; 
long l1 = atomic.incrementAndGet() ; 
long l2 = atomic.updateAndGet(l -> l*2 + 1) ;
@JosePaumard 
#50new8 
Variables atomiques 
Java 8 nous amène : 
AtomicLong atomic = new AtomicLong() ; 
long l1 = atomic.incrementAndGet() ; 
long l2 = atomic.updateAndGet(l -> l*2 + 1) ; 
long l3 = atomic.accumulateAndGet(12L, (l1, l2) -> l1 % l2) ;
@JosePaumard 
#50new8 
LongAdder 
Java 8 nous amène : 
LongAdder adder = new LongAdder() ; 
adder.increment() ; // in a thread 
adder.increment() ; // in a 2nd thread 
adder.increment() ; // in a 3rd thread 
long sum = adder.sum() ;
@JosePaumard 
#50new8 
LongAccumulator 
Idem, avec une l : 
LongAccumulator accu = 
new LongAccumulator((l1, l2) -> Long.max(l1, l2), 0L) ; 
accu.accumulate(value1) ; // in a thread 
accu.accumulate(value2) ; // in a 2nd thread 
accu.accumulate(value2) ; // in a 3rd thread 
long sum = accu.longValue() ;
@JosePaumard 
#50new8 
StampedLock 
Un lock normal, avec lecture optimiste 
long stamp = sl.writeLock() ; 
try { 
... 
} finally { 
sl.unlockWrite(stamp) ; 
} 
long stamp = sl.readLock() ; 
try { 
... 
} finally { 
sl.unlockRead(stamp) ; 
} 
StampedLock sl= new StampedLock() ;
@JosePaumard 
#50new8 
StampedLock 
Un lock normal, avec lecture optimiste 
Lecture / écriture exclusives, mais… 
long stamp = sl.writeLock() ; 
try { 
... 
} finally { 
sl.unlockWrite(stamp) ; 
} 
long stamp = sl.readLock() ; 
try { 
... 
} finally { 
sl.unlockRead(stamp) ; 
} 
StampedLock sl= new StampedLock() ;
@JosePaumard 
#50new8 
StampedLock 
Un lock normal, avec lecture optimiste 
StampedLock sl= new StampedLock() ; 
long stamp = sl.tryOptimisticRead() ; 
// here we read a variable that can be changed in another thread 
if (lock.validate(stamp)) { 
// the read was not concurrent 
} else { 
// another thread acquired a write lock 
}
Concurrent 
Concurrent 
HashMap
@JosePaumard 
#50new8 
ConcurrentHashMap 
La vieille ConcurrentHashMap V7 a été retirée 
Thread safe 
Pas de lock ≠ ConcurrentHashMap V7 
Des nouvelles méthodes (un paquet…)
@JosePaumard 
#50new8 
ConcurrentHashMap 
6000 lignes de code
@JosePaumard 
#50new8 
ConcurrentHashMap 
6000 lignes de code 
54 classes membre
@JosePaumard 
#50new8 
ConcurrentHashMap 
6000 lignes de code 
54 classes membre 
FYI : 58 classes dans tout java.util.concurrent
@JosePaumard 
#50new8 
ConcurrentHashMap 
6000 lignes de code 
54 classes membre 
FYI : 58 classes dans tout java.util.concurrent 
Nouveaux patterns !
@JosePaumard 
#50new8 
ConcurrentHashMap 
Ne jamais utiliser size() 
int count = map.size() ; // should not be used 
count = map.mappingCount() ; // new method
@JosePaumard 
#50new8 
ConcurrentHashMap 
Ne jamais utiliser size() 
int count = map.size() ; // should not be used 
long count = map.mappingCount() ; // new method
@JosePaumard 
#50new8 
ConcurrentHashMap 
Méthode search() 
search(), searchKey(), searchValue(), searchEntry() 
Retourne le 1er élément qui vérifie le prédicat 
ConcurrentHashMap<Integer, String> map = ... ; 
map.search(10L, (key, value) -> value.length() < key) ;
@JosePaumard 
#50new8 
ConcurrentHashMap 
Méthode search() 
search(), searchKey(), searchValue(), searchEntry() 
Retourne le 1er élément qui vérifie le prédicat 
ConcurrentHashMap<Integer, String> map = ... ; 
map.search(10L, (key, value) -> value.length() < key) ;
@JosePaumard 
#50new8 
ConcurrentHashMap 
Méthode search() 
Si la map contient plus de 10 éléments, la recherche aura lieu en parallèle ! 
ConcurrentHashMap<Integer, String> map = ... ; 
map.search(10L, (key, value) -> value.length() < key) ;
@JosePaumard 
#50new8 
ConcurrentHashMap 
Méthode search() 
Si la map contient plus de 10 éléments, la recherche aura lieu en parallèle ! 
On peut passer 0 ou Long.MAX_VALUE 
ConcurrentHashMap<Integer, String> map = ... ; 
map.search(10L, (key, value) -> value.length() < key) ;
@JosePaumard 
#50new8 
ConcurrentHashMap 
Méthode forEach() 
forEach(), forEachKey(), forEachEntries() 
ConcurrentHashMap<Integer, String> map = ... ; 
map.forEach(10L, 
(key, value) -> 
System.out.println(String.join(key, "->", value) 
) ;
@JosePaumard 
#50new8 
ConcurrentHashMap 
Méthode de réduction 
reduce(), reduceKey(), reduceEntries() 
ConcurrentHashMap<Integer, String> map = ... ; 
map.reduce(10L, 
(key, value) -> value.getName(), // transformation 
(name1, name2) -> name1.length() > name2.length() ? 
name1 : name2) // reduction 
) ;
@JosePaumard 
#50new8 
Pas de ConcurrentHashSet 
Mais… 
Set<String> set = ConcurrentHashMap.newKeySet() ;
@JosePaumard 
#50new8 
Pas de ConcurrentHashSet 
Mais… 
Crée une concurrent hashmap dans laquelle les valeurs sont Boolean.TRUE 
Se comporte donc comme un ConcurrentSet 
Set<String> set = ConcurrentHashMap.newKeySet() ;
Merci !
@JosePaumard 
#50new8

More Related Content

What's hot

Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016François Sarradin
 
ArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateauArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateauJosé Paumard
 
Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Jean-Michel Doudoux
 
Interface fonctionnelle, Lambda expression, méthode par défaut, référence de...
Interface fonctionnelle, Lambda expression, méthode par défaut,  référence de...Interface fonctionnelle, Lambda expression, méthode par défaut,  référence de...
Interface fonctionnelle, Lambda expression, méthode par défaut, référence de...MICHRAFY MUSTAFA
 
Javascript pour les développeurs Java : quels sont les pièges à éviter ?
Javascript pour les développeurs Java : quels sont les pièges à éviter ?Javascript pour les développeurs Java : quels sont les pièges à éviter ?
Javascript pour les développeurs Java : quels sont les pièges à éviter ?FlorianBoulay
 
Asyncio: offrez des tulipes à vos entrées sorties asynchrones
Asyncio: offrez des tulipes à vos entrées sorties asynchronesAsyncio: offrez des tulipes à vos entrées sorties asynchrones
Asyncio: offrez des tulipes à vos entrées sorties asynchronestchappui
 
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Normandy JUG
 
Techday Arrow Group: Java 8
Techday Arrow Group: Java 8Techday Arrow Group: Java 8
Techday Arrow Group: Java 8Arrow Group
 
Programmation fonctionnelle
Programmation fonctionnelleProgrammation fonctionnelle
Programmation fonctionnelleGeeks Anonymes
 
Les concepts de la programmation fonctionnelle illustrés avec java 8
Les concepts de la programmation fonctionnelle illustrés avec java 8Les concepts de la programmation fonctionnelle illustrés avec java 8
Les concepts de la programmation fonctionnelle illustrés avec java 8Yannick Chartois
 
Cassandra Spark Lan Party at Devoxx France
Cassandra Spark Lan Party at Devoxx FranceCassandra Spark Lan Party at Devoxx France
Cassandra Spark Lan Party at Devoxx FranceJérémy Sevellec
 
De java à swift en 2 temps trois mouvements
De java à swift en 2 temps trois mouvementsDe java à swift en 2 temps trois mouvements
De java à swift en 2 temps trois mouvementsDidier Plaindoux
 
Monitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et PinbaMonitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et PinbaPatrick Allaert
 
Librairies Java qui changent la vie
Librairies Java qui changent la vieLibrairies Java qui changent la vie
Librairies Java qui changent la viecluelessjoe
 
Introduction à l'analyse de réseaux avec R
Introduction à l'analyse de réseaux avec RIntroduction à l'analyse de réseaux avec R
Introduction à l'analyse de réseaux avec RLaurent Beauguitte
 
Coat::Persistent at FPW2009
Coat::Persistent at FPW2009Coat::Persistent at FPW2009
Coat::Persistent at FPW2009Alexis Sukrieh
 

What's hot (20)

Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016Java (8) eXperiments - DevoxxFR 2016
Java (8) eXperiments - DevoxxFR 2016
 
ArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateauArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateau
 
Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016Retours sur java 8 devoxx fr 2016
Retours sur java 8 devoxx fr 2016
 
Interface fonctionnelle, Lambda expression, méthode par défaut, référence de...
Interface fonctionnelle, Lambda expression, méthode par défaut,  référence de...Interface fonctionnelle, Lambda expression, méthode par défaut,  référence de...
Interface fonctionnelle, Lambda expression, méthode par défaut, référence de...
 
Javascript pour les développeurs Java : quels sont les pièges à éviter ?
Javascript pour les développeurs Java : quels sont les pièges à éviter ?Javascript pour les développeurs Java : quels sont les pièges à éviter ?
Javascript pour les développeurs Java : quels sont les pièges à éviter ?
 
Asyncio: offrez des tulipes à vos entrées sorties asynchrones
Asyncio: offrez des tulipes à vos entrées sorties asynchronesAsyncio: offrez des tulipes à vos entrées sorties asynchrones
Asyncio: offrez des tulipes à vos entrées sorties asynchrones
 
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
Fork / Join, Parallel Arrays, Lambdas : la programmation parallèle (trop ?) f...
 
Techday Arrow Group: Java 8
Techday Arrow Group: Java 8Techday Arrow Group: Java 8
Techday Arrow Group: Java 8
 
Programmation fonctionnelle
Programmation fonctionnelleProgrammation fonctionnelle
Programmation fonctionnelle
 
Programmation Fonctionnelle
Programmation FonctionnelleProgrammation Fonctionnelle
Programmation Fonctionnelle
 
Les concepts de la programmation fonctionnelle illustrés avec java 8
Les concepts de la programmation fonctionnelle illustrés avec java 8Les concepts de la programmation fonctionnelle illustrés avec java 8
Les concepts de la programmation fonctionnelle illustrés avec java 8
 
Cassandra Spark Lan Party at Devoxx France
Cassandra Spark Lan Party at Devoxx FranceCassandra Spark Lan Party at Devoxx France
Cassandra Spark Lan Party at Devoxx France
 
De java à swift en 2 temps trois mouvements
De java à swift en 2 temps trois mouvementsDe java à swift en 2 temps trois mouvements
De java à swift en 2 temps trois mouvements
 
Monitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et PinbaMonitoring d'applications/environnements PHP: APM et Pinba
Monitoring d'applications/environnements PHP: APM et Pinba
 
Java SE 7
Java SE 7Java SE 7
Java SE 7
 
Librairies Java qui changent la vie
Librairies Java qui changent la vieLibrairies Java qui changent la vie
Librairies Java qui changent la vie
 
Introduction à l'analyse de réseaux avec R
Introduction à l'analyse de réseaux avec RIntroduction à l'analyse de réseaux avec R
Introduction à l'analyse de réseaux avec R
 
Coat::Persistent at FPW2009
Coat::Persistent at FPW2009Coat::Persistent at FPW2009
Coat::Persistent at FPW2009
 
Ce bon vieux propel
Ce bon vieux propelCe bon vieux propel
Ce bon vieux propel
 
Langage Perl
Langage PerlLangage Perl
Langage Perl
 

Viewers also liked

50 new things we can do with Java 8
50 new things we can do with Java 850 new things we can do with Java 8
50 new things we can do with Java 8José Paumard
 
JFokus 50 new things with java 8
JFokus 50 new things with java 8JFokus 50 new things with java 8
JFokus 50 new things with java 8José Paumard
 
Going reactive in java
Going reactive in javaGoing reactive in java
Going reactive in javaJosé Paumard
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developersJosé Paumard
 
Linked to ArrayList: the full story
Linked to ArrayList: the full storyLinked to ArrayList: the full story
Linked to ArrayList: the full storyJosé Paumard
 
Java 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelizationJava 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelizationJosé Paumard
 
Autumn collection JavaOne 2014
Autumn collection JavaOne 2014Autumn collection JavaOne 2014
Autumn collection JavaOne 2014José Paumard
 
HighLoad++ 2009 In-Memory Data Grids
HighLoad++ 2009 In-Memory Data GridsHighLoad++ 2009 In-Memory Data Grids
HighLoad++ 2009 In-Memory Data GridsAlexey Kharlamov
 
Async Gateway или Разработка системы распределенных вычислений с нуля
Async Gateway или Разработка системы распределенных вычислений с нуляAsync Gateway или Разработка системы распределенных вычислений с нуля
Async Gateway или Разработка системы распределенных вычислений с нуляVitebsk Miniq
 
Phoenix for Rubyists
Phoenix for RubyistsPhoenix for Rubyists
Phoenix for RubyistsMike North
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSuzquiano
 
Алексей Николаенков, Devexperts
Алексей Николаенков, DevexpertsАлексей Николаенков, Devexperts
Алексей Николаенков, DevexpertsNata_Churda
 
Hazelcast for Terracotta Users
Hazelcast for Terracotta UsersHazelcast for Terracotta Users
Hazelcast for Terracotta UsersHazelcast
 
Amazon cloud – готовим вместе
Amazon cloud – готовим вместеAmazon cloud – готовим вместе
Amazon cloud – готовим вместеVitebsk Miniq
 
Gamification in outsourcing company: experience report.
Gamification in outsourcing company: experience report.Gamification in outsourcing company: experience report.
Gamification in outsourcing company: experience report.Mikalai Alimenkou
 
Java 8, the Good, the Bad and the Ugly
Java 8, the Good, the Bad and the UglyJava 8, the Good, the Bad and the Ugly
Java 8, the Good, the Bad and the UglyMikalai Alimenkou
 
Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт GuavaEgor Chernyshev
 

Viewers also liked (20)

50 new things we can do with Java 8
50 new things we can do with Java 850 new things we can do with Java 8
50 new things we can do with Java 8
 
JFokus 50 new things with java 8
JFokus 50 new things with java 8JFokus 50 new things with java 8
JFokus 50 new things with java 8
 
Going reactive in java
Going reactive in javaGoing reactive in java
Going reactive in java
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developers
 
Linked to ArrayList: the full story
Linked to ArrayList: the full storyLinked to ArrayList: the full story
Linked to ArrayList: the full story
 
Java 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelizationJava 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelization
 
Autumn collection JavaOne 2014
Autumn collection JavaOne 2014Autumn collection JavaOne 2014
Autumn collection JavaOne 2014
 
HighLoad++ 2009 In-Memory Data Grids
HighLoad++ 2009 In-Memory Data GridsHighLoad++ 2009 In-Memory Data Grids
HighLoad++ 2009 In-Memory Data Grids
 
Async Gateway или Разработка системы распределенных вычислений с нуля
Async Gateway или Разработка системы распределенных вычислений с нуляAsync Gateway или Разработка системы распределенных вычислений с нуля
Async Gateway или Разработка системы распределенных вычислений с нуля
 
Phoenix for Rubyists
Phoenix for RubyistsPhoenix for Rubyists
Phoenix for Rubyists
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMS
 
Алексей Николаенков, Devexperts
Алексей Николаенков, DevexpertsАлексей Николаенков, Devexperts
Алексей Николаенков, Devexperts
 
Code review at large scale
Code review at large scaleCode review at large scale
Code review at large scale
 
Hazelcast for Terracotta Users
Hazelcast for Terracotta UsersHazelcast for Terracotta Users
Hazelcast for Terracotta Users
 
Amazon cloud – готовим вместе
Amazon cloud – готовим вместеAmazon cloud – готовим вместе
Amazon cloud – готовим вместе
 
ЖК Зорге 9
ЖК Зорге 9ЖК Зорге 9
ЖК Зорге 9
 
Gamification in outsourcing company: experience report.
Gamification in outsourcing company: experience report.Gamification in outsourcing company: experience report.
Gamification in outsourcing company: experience report.
 
Java 8, the Good, the Bad and the Ugly
Java 8, the Good, the Bad and the UglyJava 8, the Good, the Bad and the Ugly
Java 8, the Good, the Bad and the Ugly
 
Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт Guava
 

Similar to 50 nouvelles choses que l'on peut faire en Java 8

201303 - Java8
201303 - Java8201303 - Java8
201303 - Java8lyonjug
 
Future of java script web version
Future of java script web versionFuture of java script web version
Future of java script web versionSébastien Pertus
 
Réu technodejs
Réu technodejsRéu technodejs
Réu technodejsnaholyr
 
Hands on lab Elasticsearch
Hands on lab ElasticsearchHands on lab Elasticsearch
Hands on lab ElasticsearchDavid Pilato
 
Beyond F5 - windbg et .Net
Beyond F5 - windbg et .NetBeyond F5 - windbg et .Net
Beyond F5 - windbg et .NetYann Schwartz
 
Partie1 TypeScript
Partie1 TypeScriptPartie1 TypeScript
Partie1 TypeScriptHabib Ayad
 
Android Optimisations Greendroid
Android Optimisations GreendroidAndroid Optimisations Greendroid
Android Optimisations GreendroidGDG Nantes
 
Eric Moreau: Fluent interfaces
Eric Moreau: Fluent interfacesEric Moreau: Fluent interfaces
Eric Moreau: Fluent interfacesMSDEVMTL
 
Cycle de vie d'activité Android et les composant d'Android
Cycle de vie d'activité Android et les composant d'AndroidCycle de vie d'activité Android et les composant d'Android
Cycle de vie d'activité Android et les composant d'AndroidHoussem Lahiani
 
Cycle de vie d'activité Android et les composant d'Android
Cycle de vie d'activité Android et les composant d'AndroidCycle de vie d'activité Android et les composant d'Android
Cycle de vie d'activité Android et les composant d'AndroidHoussem Lahiani
 
BEBUTANT JAVA
BEBUTANT  JAVABEBUTANT  JAVA
BEBUTANT JAVAviolonjo
 
Lect14 dev2
Lect14 dev2Lect14 dev2
Lect14 dev2moisko
 

Similar to 50 nouvelles choses que l'on peut faire en Java 8 (14)

201303 - Java8
201303 - Java8201303 - Java8
201303 - Java8
 
Future of java script web version
Future of java script web versionFuture of java script web version
Future of java script web version
 
Réu technodejs
Réu technodejsRéu technodejs
Réu technodejs
 
Hands on lab Elasticsearch
Hands on lab ElasticsearchHands on lab Elasticsearch
Hands on lab Elasticsearch
 
Spring 3.0
Spring 3.0Spring 3.0
Spring 3.0
 
Beyond F5 - windbg et .Net
Beyond F5 - windbg et .NetBeyond F5 - windbg et .Net
Beyond F5 - windbg et .Net
 
Partie1 TypeScript
Partie1 TypeScriptPartie1 TypeScript
Partie1 TypeScript
 
Android Optimisations Greendroid
Android Optimisations GreendroidAndroid Optimisations Greendroid
Android Optimisations Greendroid
 
Change mind about JS
Change mind about JSChange mind about JS
Change mind about JS
 
Eric Moreau: Fluent interfaces
Eric Moreau: Fluent interfacesEric Moreau: Fluent interfaces
Eric Moreau: Fluent interfaces
 
Cycle de vie d'activité Android et les composant d'Android
Cycle de vie d'activité Android et les composant d'AndroidCycle de vie d'activité Android et les composant d'Android
Cycle de vie d'activité Android et les composant d'Android
 
Cycle de vie d'activité Android et les composant d'Android
Cycle de vie d'activité Android et les composant d'AndroidCycle de vie d'activité Android et les composant d'Android
Cycle de vie d'activité Android et les composant d'Android
 
BEBUTANT JAVA
BEBUTANT  JAVABEBUTANT  JAVA
BEBUTANT JAVA
 
Lect14 dev2
Lect14 dev2Lect14 dev2
Lect14 dev2
 

More from José Paumard

Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19José Paumard
 
From Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdfFrom Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdfJosé Paumard
 
The Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern MatchingThe Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern MatchingJosé Paumard
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKJosé Paumard
 
Designing functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patternsDesigning functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patternsJosé Paumard
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of FlatteryJosé Paumard
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of FlatteryJosé Paumard
 
Designing functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor PatternDesigning functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor PatternJosé Paumard
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapesJosé Paumard
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!José Paumard
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2José Paumard
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1José Paumard
 
Asynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowAsynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowJosé Paumard
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJosé Paumard
 
Collectors in the Wild
Collectors in the WildCollectors in the Wild
Collectors in the WildJosé Paumard
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJosé Paumard
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureJosé Paumard
 

More from José Paumard (20)

Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19Loom Virtual Threads in the JDK 19
Loom Virtual Threads in the JDK 19
 
From Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdfFrom Java 11 to 17 and beyond.pdf
From Java 11 to 17 and beyond.pdf
 
The Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern MatchingThe Future of Java: Records, Sealed Classes and Pattern Matching
The Future of Java: Records, Sealed Classes and Pattern Matching
 
Deep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UKDeep Dive Java 17 Devoxx UK
Deep Dive Java 17 Devoxx UK
 
Designing functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patternsDesigning functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patterns
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Designing functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor PatternDesigning functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor Pattern
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapes
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
 
Asynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowAsynchronous Systems with Fn Flow
Asynchronous Systems with Fn Flow
 
Java Full Throttle
Java Full ThrottleJava Full Throttle
Java Full Throttle
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
 
Collectors in the Wild
Collectors in the WildCollectors in the Wild
Collectors in the Wild
 
Streams in the wild
Streams in the wildStreams in the wild
Streams in the wild
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridge
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
 

Recently uploaded

Computer Parts in French - Les parties de l'ordinateur.pptx
Computer Parts in French - Les parties de l'ordinateur.pptxComputer Parts in French - Les parties de l'ordinateur.pptx
Computer Parts in French - Les parties de l'ordinateur.pptxRayane619450
 
Chapitre 2 du cours de JavaScript. Bon Cours
Chapitre 2 du cours de JavaScript. Bon CoursChapitre 2 du cours de JavaScript. Bon Cours
Chapitre 2 du cours de JavaScript. Bon Coursebenezerngoran
 
Boléro. pptx Film français réalisé par une femme.
Boléro.  pptx   Film   français   réalisé  par une  femme.Boléro.  pptx   Film   français   réalisé  par une  femme.
Boléro. pptx Film français réalisé par une femme.Txaruka
 
Apolonia, Apolonia.pptx Film documentaire
Apolonia, Apolonia.pptx         Film documentaireApolonia, Apolonia.pptx         Film documentaire
Apolonia, Apolonia.pptx Film documentaireTxaruka
 
Intégration des TICE dans l'enseignement de la Physique-Chimie.pptx
Intégration des TICE dans l'enseignement de la Physique-Chimie.pptxIntégration des TICE dans l'enseignement de la Physique-Chimie.pptx
Intégration des TICE dans l'enseignement de la Physique-Chimie.pptxabdououanighd
 
La nouvelle femme . pptx Film français
La   nouvelle   femme  . pptx  Film françaisLa   nouvelle   femme  . pptx  Film français
La nouvelle femme . pptx Film françaisTxaruka
 
L'expression du but : fiche et exercices niveau C1 FLE
L'expression du but : fiche et exercices  niveau C1 FLEL'expression du but : fiche et exercices  niveau C1 FLE
L'expression du but : fiche et exercices niveau C1 FLElebaobabbleu
 
Cours ofppt du Trade-Marketing-Présentation.pdf
Cours ofppt du Trade-Marketing-Présentation.pdfCours ofppt du Trade-Marketing-Présentation.pdf
Cours ofppt du Trade-Marketing-Présentation.pdfachrafbrahimi1
 
Formation qhse - GIASE saqit_105135.pptx
Formation qhse - GIASE saqit_105135.pptxFormation qhse - GIASE saqit_105135.pptx
Formation qhse - GIASE saqit_105135.pptxrajaakiass01
 
L application de la physique classique dans le golf.pptx
L application de la physique classique dans le golf.pptxL application de la physique classique dans le golf.pptx
L application de la physique classique dans le golf.pptxhamzagame
 
GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...
GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...
GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...Nguyen Thanh Tu Collection
 
CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...
CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...
CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...Universidad Complutense de Madrid
 
Cours Préparation à l’ISO 27001 version 2022.pdf
Cours Préparation à l’ISO 27001 version 2022.pdfCours Préparation à l’ISO 27001 version 2022.pdf
Cours Préparation à l’ISO 27001 version 2022.pdfssuserc72852
 
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptxCopie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptxikospam0
 
Sidonie au Japon . pptx Un film français
Sidonie    au   Japon  .  pptx  Un film françaisSidonie    au   Japon  .  pptx  Un film français
Sidonie au Japon . pptx Un film françaisTxaruka
 
Les roches magmatique géodynamique interne.pptx
Les roches magmatique géodynamique interne.pptxLes roches magmatique géodynamique interne.pptx
Les roches magmatique géodynamique interne.pptxShinyaHilalYamanaka
 
Bilan énergétique des chambres froides.pdf
Bilan énergétique des chambres froides.pdfBilan énergétique des chambres froides.pdf
Bilan énergétique des chambres froides.pdfAmgdoulHatim
 
RAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANK
RAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANKRAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANK
RAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANKNassimaMdh
 
Formation échiquéenne jwhyCHESS, parallèle avec la planification de projet
Formation échiquéenne jwhyCHESS, parallèle avec la planification de projetFormation échiquéenne jwhyCHESS, parallèle avec la planification de projet
Formation échiquéenne jwhyCHESS, parallèle avec la planification de projetJeanYvesMoine
 
La mondialisation avantages et inconvénients
La mondialisation avantages et inconvénientsLa mondialisation avantages et inconvénients
La mondialisation avantages et inconvénientsJaouadMhirach
 

Recently uploaded (20)

Computer Parts in French - Les parties de l'ordinateur.pptx
Computer Parts in French - Les parties de l'ordinateur.pptxComputer Parts in French - Les parties de l'ordinateur.pptx
Computer Parts in French - Les parties de l'ordinateur.pptx
 
Chapitre 2 du cours de JavaScript. Bon Cours
Chapitre 2 du cours de JavaScript. Bon CoursChapitre 2 du cours de JavaScript. Bon Cours
Chapitre 2 du cours de JavaScript. Bon Cours
 
Boléro. pptx Film français réalisé par une femme.
Boléro.  pptx   Film   français   réalisé  par une  femme.Boléro.  pptx   Film   français   réalisé  par une  femme.
Boléro. pptx Film français réalisé par une femme.
 
Apolonia, Apolonia.pptx Film documentaire
Apolonia, Apolonia.pptx         Film documentaireApolonia, Apolonia.pptx         Film documentaire
Apolonia, Apolonia.pptx Film documentaire
 
Intégration des TICE dans l'enseignement de la Physique-Chimie.pptx
Intégration des TICE dans l'enseignement de la Physique-Chimie.pptxIntégration des TICE dans l'enseignement de la Physique-Chimie.pptx
Intégration des TICE dans l'enseignement de la Physique-Chimie.pptx
 
La nouvelle femme . pptx Film français
La   nouvelle   femme  . pptx  Film françaisLa   nouvelle   femme  . pptx  Film français
La nouvelle femme . pptx Film français
 
L'expression du but : fiche et exercices niveau C1 FLE
L'expression du but : fiche et exercices  niveau C1 FLEL'expression du but : fiche et exercices  niveau C1 FLE
L'expression du but : fiche et exercices niveau C1 FLE
 
Cours ofppt du Trade-Marketing-Présentation.pdf
Cours ofppt du Trade-Marketing-Présentation.pdfCours ofppt du Trade-Marketing-Présentation.pdf
Cours ofppt du Trade-Marketing-Présentation.pdf
 
Formation qhse - GIASE saqit_105135.pptx
Formation qhse - GIASE saqit_105135.pptxFormation qhse - GIASE saqit_105135.pptx
Formation qhse - GIASE saqit_105135.pptx
 
L application de la physique classique dans le golf.pptx
L application de la physique classique dans le golf.pptxL application de la physique classique dans le golf.pptx
L application de la physique classique dans le golf.pptx
 
GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...
GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...
GIÁO ÁN DẠY THÊM (KẾ HOẠCH BÀI DẠY BUỔI 2) - TIẾNG ANH 6, 7 GLOBAL SUCCESS (2...
 
CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...
CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...
CompLit - Journal of European Literature, Arts and Society - n. 7 - Table of ...
 
Cours Préparation à l’ISO 27001 version 2022.pdf
Cours Préparation à l’ISO 27001 version 2022.pdfCours Préparation à l’ISO 27001 version 2022.pdf
Cours Préparation à l’ISO 27001 version 2022.pdf
 
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptxCopie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
Copie de Engineering Software Marketing Plan by Slidesgo.pptx.pptx
 
Sidonie au Japon . pptx Un film français
Sidonie    au   Japon  .  pptx  Un film françaisSidonie    au   Japon  .  pptx  Un film français
Sidonie au Japon . pptx Un film français
 
Les roches magmatique géodynamique interne.pptx
Les roches magmatique géodynamique interne.pptxLes roches magmatique géodynamique interne.pptx
Les roches magmatique géodynamique interne.pptx
 
Bilan énergétique des chambres froides.pdf
Bilan énergétique des chambres froides.pdfBilan énergétique des chambres froides.pdf
Bilan énergétique des chambres froides.pdf
 
RAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANK
RAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANKRAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANK
RAPPORT DE STAGE D'INTERIM DE ATTIJARIWAFA BANK
 
Formation échiquéenne jwhyCHESS, parallèle avec la planification de projet
Formation échiquéenne jwhyCHESS, parallèle avec la planification de projetFormation échiquéenne jwhyCHESS, parallèle avec la planification de projet
Formation échiquéenne jwhyCHESS, parallèle avec la planification de projet
 
La mondialisation avantages et inconvénients
La mondialisation avantages et inconvénientsLa mondialisation avantages et inconvénients
La mondialisation avantages et inconvénients
 

50 nouvelles choses que l'on peut faire en Java 8

  • 1. @JosePaumard nouvelles choses que l’on peut faire avec Java
  • 2. @JosePaumard Java nouvelles choses que l’on peut faire avec
  • 3. @JosePaumard Java nouvelles choses que l’on peut faire avec
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 10. Date
  • 11. @JosePaumard #50new8 Date : Instant Un Instant est un point sur une timeline Instant start = Instant.now() ; Instant end = Instant.now() ;
  • 12. @JosePaumard #50new8 Date : Duration Une « duration » est le temps entre deux Instant Instant start = Instant.now() ; Instant end = Instant.now() ; Duration elapsed = Duration.between(start, end) ; long millis = elapsed.toMillis() ;
  • 13. @JosePaumard #50new8 Date : Duration On a une arithmétique sur les « Duration » Instant start = Instant.now() ; Instant end = Instant.now() ; Duration elapsed = Duration.between(start, end) ; long millis = elapsed.toMillis() ; elapsed.plus(2L, TemporalUnit.SECONDS) ;
  • 14. @JosePaumard #50new8 Date : Duration La précision de la time line est de 10-9 s (nanosecond)
  • 15. @JosePaumard #50new8 Date : Duration La précision de la time line est de 10-9 s (nanosecond) Bonne précision ?
  • 16. @JosePaumard #50new8 Date : Duration La précision de la time line est de 10-9 s (nanosecond) Bonne précision ? La demie-vie du boson de Higgs est de 10-23 s
  • 17. @JosePaumard #50new8 Date : LocalDate Une « LocalDate » est une date de tous les jours LocalDate now = LocalDate.now() ; LocalDate shakespeareDoB = LocaleDate.of(1564, Month.APRIL, 23) ;
  • 18. @JosePaumard #50new8 Date : Period Une « Period » est le temps entre deux LocalDate LocalDate now = LocalDate.now() ; LocalDate shakespeareDoB = LocaleDate.of(1564, Month.APRIL, 23) ; Period p = shakespeareDoB.until(now) ; System.out.println("# years = " + p.getYears()) ;
  • 19. @JosePaumard #50new8 Date : Period Une « Period » est le temps entre deux LocalDate LocalDate now = LocalDate.now() ; LocalDate shakespeareDoB = LocaleDate.of(1564, Month.APRIL, 23) ; Period p = shakespeareDoB.until(now) ; System.out.println("# years = " + p.getYears()) ; long days = shakespeareDoB.until(now, ChronoUnit.DAYS) ; System.out.println("# days = " + days) ;
  • 20. @JosePaumard #50new8 Date : TemporalAdjuster On a une arithmétique sur les « local date » LocalDate now = LocalDate.now() ; LocalDate nextSunday = now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
  • 21. @JosePaumard #50new8 Date : TemporalAdjuster On a une arithmétique sur les « local date » Une boîte à outils de 14 méthodes statiques firstDayOfMonth(), lastDayOfYear() firstDayOfNextMonth() LocalDate now = LocalDate.now() ; LocalDate nextSunday = now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
  • 22. @JosePaumard #50new8 Date : TemporalAdjuster On a une arithmétique sur les « local date » Une boîte à outils de 14 méthodes statiques firstInMonth(DayOfWeek.MONDAY) next(DayOfWeek.FRIDAY) LocalDate now = LocalDate.now() ; LocalDate nextSunday = now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
  • 23. @JosePaumard #50new8 Date : LocalTime Un « LocalTime » est un heure de tous les jours : ex. 10:20 LocalTime now = LocalTime.now() ; LocalTime time = LocalTime.of(10, 20) ; // 10:20
  • 24. @JosePaumard #50new8 Date : LocalTime Un « LocalTime » est un heure de tous les jours : ex. 10:20 LocalTime now = LocalTime.now() ; LocalTime time = LocalTime.of(10, 20) ; // 10:20 LocalTime lunchTime = LocalTime.of(12, 30) ; LocalTime coffeeTime = lunchTime.plusHours(2) ; // 14:20
  • 25. @JosePaumard #50new8 Date : ZonedTime Utiles pour les dates localisées Set<String> allZonesIds = ZoneId.getAvailableZoneIds() ; String ukTZ = ZoneId.of("Europe/London") ;
  • 26. @JosePaumard #50new8 Date : ZonedTime Utiles pour les dates localisées System.out.println( ZonedDateTime.of( 1564, Month.APRIL.getValue(), 23, // year / month / day 10, 0, 0, 0, // h / mn / s / nanos ZoneId.of("Europe/London")) ); // prints 1564-04-23T10:00-00:01:15[Europe/London]
  • 27. @JosePaumard #50new8 Date : ZonedTime On a aussi une arithmétique dessus ZonedDateTime currentMeeting = ZonedDateTime.of( LocalDate.of(2014, Month.APRIL, 18), // LocalDate LocalTime.of(9, 30), // LocalTime ZoneId.of("Europe/London") ); ZonedDateTime nextMeeting = currentMeeting.plus(Period.ofMonth(1));
  • 28. @JosePaumard #50new8 Date : ZonedTime On a aussi une arithmétique dessus ZonedDateTime currentMeeting = ZonedDateTime.of( LocalDate.of(2014, Month.APRIL, 18), // LocalDate LocalTime.of(9, 30), // LocalTime ZoneId.of("Europe/London") ); ZonedDateTime nextMeeting = currentMeeting.plus(Period.ofMonth(1)) ; ZonedDateTime nextMeetingUS = nextMeeting.withZoneSameInstant(ZoneId.of("US/Central")) ;
  • 29. @JosePaumard #50new8 Date : Formatter Classe factory : DateTimeFormatter ZonedDateTime nextMeetingUS = nextMeeting.withZoneSameInstant(ZoneId.of("US/Central")); System.out.println( DateTimeFormatter.ISO_DATE_TIME.format(nextMeetingUS) ); // prints 2014-04-12T03:30:00-05:00[US/Central] System.out.println( DateTimeFormatter.RFC_1123_DATE_TIME.format(nextMeetingUS) ); // prints Sat, 12 Apr 2014 03:30:00 -0500
  • 30. @JosePaumard #50new8 Date : liens avec java.util.Date Date & Time API vs java.util.Date Date date = Date.from(instant); // API -> legacy Instant instant = date.toInstant(); // legacy -> new API
  • 31. @JosePaumard #50new8 Date : liens avec java.util.Date Date & Time API vs java.util.Date TimeStamp time = TimeStamp.from(instant); // API -> legacy Instant instant = time.toInstant(); // legacy -> new API Date date = Date.from(instant); // API -> legacy Instant instant = date.toInstant(); // legacy -> new API
  • 32. @JosePaumard #50new8 Date : liens avec java.util.Date Date & Time API vs java.util.Date Date date = Date.from(localDate); // API -> legacy LocalDate localDate = date.toLocalDate(); // legacy -> new API TimeStamp time = TimeStamp.from(instant); // API -> legacy Instant instant = time.toInstant(); // legacy -> new API Date date = Date.from(instant); // API -> legacy Instant instant = date.toInstant(); // legacy -> new API
  • 33. @JosePaumard #50new8 Date : liens avec java.util.Date Date & Time API vs java.util.Date Time time = Time.from(localTime); // API -> legacy LocalTime localTime = time.toLocalTime(); // legacy -> new API Date date = Date.from(localDate); // API -> legacy LocalDate localDate = date.toLocalDate(); // legacy -> new API TimeStamp time = TimeStamp.from(instant); // API -> legacy Instant instant = time.toInstant(); // legacy -> new API Date date = Date.from(instant); // API -> legacy Instant instant = date.toInstant(); // legacy -> new API
  • 35. @JosePaumard #50new8 String : Stream Un Stream sur les lettres qui composent une String String s = "hello"; IntStream stream = s.chars(); // stream on the letters of s
  • 36. @JosePaumard #50new8 String : Stream Un Stream sur les lettres qui composent une String String s = "hello"; IntStream stream = s.chars(); // stream on the letters of s s.chars() .map(Character::toUpperCase) .forEach(System.out::println);
  • 37. @JosePaumard #50new8 String : Stream Un Stream sur les lettres qui composent une String String s = "hello"; IntStream stream = s.chars(); // stream on the letters of s s.chars() .map(Character::toUpperCase) .forEach(System.out::println); > HELLO 7269767679
  • 38. @JosePaumard #50new8 String : Stream Un Stream sur les lettres qui composent une String String s = "hello"; IntStream stream = s.chars(); // stream on the letters of s s.chars() // IntStream .map(Character::toUpperCase) .forEach(System.out::println); // Prints an int! > 7269767679
  • 39. @JosePaumard #50new8 String : Stream Un Stream sur les lettres qui composent une String String s = "hello"; IntStream stream = s.chars(); // stream on the letters of s s.chars() // IntStream .mapToObj(letter -> (char)letter) // Stream<Character> .map(Character::toUpperCase) .forEach(System.out::println); // Prints a Character > HELLO
  • 40. @JosePaumard #50new8 String : expressions régulières Un Stream sur une expression régulière // book is a looooooooong String Stream<String> words = Pattern .compile("[^p{javaLetter}]") .splitAsStream(book) ;
  • 41. @JosePaumard #50new8 String : concaténation Le débutant écrit : String s1 = "hello" ; String s2 = " world!" ; String s3 = s1 + " " + s2 ;
  • 42. @JosePaumard #50new8 String : concaténation L’ignorant lui dit d’écrire : StringBuffer sb1 = new StringBuffer("hello") ; sb1.append(" world") ; String s3 = sb1.toString() ; (et il a tord)
  • 43. @JosePaumard #50new8 String : concaténation Le développeur expérimenté lui dit d’écrire : StringBuilder sb1 = new StringBuilder("hello") ; sb1.append(" world") ; String s3 = sb1.toString() ; (et il se trompe aussi…)
  • 44. @JosePaumard #50new8 String : concaténation Parce que le débutant a raison (même s’il ne le sait pas) String s1 = "hello" ; String s2 = " world!" ; String s3 = s1 + " " + s2 ; LINENUMBER 10 L2 NEW java/lang/StringBuilder DUP ALOAD 1 INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String; INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V LDC " " INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder; ALOAD 2 INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder; INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String; ASTORE 3
  • 45. @JosePaumard #50new8 String : concaténation L’expert Java 8 écrit : // The JDK 8 way StringJoiner sj = new StringJoiner(", ") ; sj.add("one").add("two").add("three") ; String s = sj.toString() ; System.out.println(s) ;
  • 46. @JosePaumard #50new8 String : concaténation L’expert Java 8 écrit : Ce qui écrit : // The JDK 8 way StringJoiner sj = new StringJoiner(", ") ; sj.add("one").add("two").add("three") ; String s = sj.toString() ; System.out.println(s) ; > one, two, three
  • 47. @JosePaumard #50new8 String : concaténation L’expert Java 8 écrit : Ce qui écrit : // The JDK 8 way StringJoiner sj = new StringJoiner(", ") ; sj.add("one") ; String s = sj.toString() ; System.out.println(s) ; > one
  • 48. @JosePaumard #50new8 String : concaténation L’expert Java 8 écrit : Ce qui écrit : // The JDK 8 way StringJoiner sj = new StringJoiner(", ", "{", "}") ; sj.add("one").add("two").add("three") ; String s = sj.toString() ; System.out.println(s) ; > {one, two, three}
  • 49. @JosePaumard #50new8 String : concaténation L’expert Java 8 écrit : Ce qui écrit : // The JDK 8 way StringJoiner sj = new StringJoiner(", ", "{", "}") ; sj.add("one") ; String s = sj.toString() ; System.out.println(s) ; > {one}
  • 50. @JosePaumard #50new8 String : concaténation L’expert Java 8 écrit : Ce qui écrit : // The JDK 8 way StringJoiner sj = new StringJoiner(", ", "{", "}") ; // we dont put anything in it String s = sj.toString() ; System.out.println(s) ; > {}
  • 51. @JosePaumard #50new8 String : concaténation Et on peut presque le faire de la classe String : Ce qui écrit : // From the String class, with a vararg String s = String.join(", ", "one", "two", "three"); System.out.println(s); > one, two, three
  • 52. @JosePaumard #50new8 String : concaténation Et on peut presque le faire de la classe String : Ce qui écrit : // From the String class, with an Iterable String [] tab = {"one", "two", "three"} ; String s = String.join(", ", tab) ; System.out.println(s) ; > one, two, three
  • 54. @JosePaumard #50new8 Nombres : nouvelles méthodes Méthodes max, min, sum // max method available on number wrapper classes long max = Long.max(1L, 2L); long sum = Long.sum(1L, 2L);
  • 55. @JosePaumard #50new8 Nombres : nouvelles méthodes Méthodes max, min, sum Si utile que ça ? // max method available on number wrapper classes long max = Long.max(1L, 2L); long sum = Long.sum(1L, 2L);
  • 56. @JosePaumard #50new8 Nombres : nouvelles méthodes Méthodes max, min, sum Si utile que ça ? // max method available on number wrapper classes long max = Long.max(1L, 2L); long sum = Long.sum(1L, 2L); persons.stream() .map(Person::getAge) .reduce(0, (a1, a2) -> Integer.max(a1, a2));
  • 57. @JosePaumard #50new8 Nombres : nouvelles méthodes Méthodes max, min, sum Si utile que ça ? Utile pour écrire des method references // max method available on number wrapper classes long max = Long.max(1L, 2L); long sum = Long.sum(1L, 2L); persons.stream() .map(Person::getAge) .reduce(0, Integer::max);
  • 58. @JosePaumard #50new8 Nombres : nouvelles méthodes Méthodes max, min, sum // max method available on number wrapper classes long max = Long.max(1L, 2L); long sum = Long.sum(1L, 2L); persons.stream() .mapToInt(Person::getAge) .max();
  • 59. @JosePaumard #50new8 Nombres : nouvelles méthodes Méthodes max, min, sum // max method available on number wrapper classes long max = Long.max(1L, 2L); long sum = Long.sum(1L, 2L); persons.stream() .max(Comparator.comparingBy(Person::getAge));
  • 60. @JosePaumard #50new8 Nombres : nouvelles méthodes Calcul de code du hachage // JDK 7 long l = 3141592653589793238L; int hash = new Long(l).hashCode(); // -1985256439
  • 61. @JosePaumard #50new8 Nombres : nouvelles méthodes Calcul de code du hachage // JDK 7 long l = 3141592653589793238L; int hash = new Long(l).hashCode(); // -1985256439 // JDK 8 long l = 3141592653589793238L; int hash = Long.hashCode(l); // -1985256439
  • 62. I/O
  • 63. @JosePaumard #50new8 I/O : lecture de fichiers texte Stream étend AutoCloseable // Java 7 : try with resources and use of Paths Path path = Paths.get("d:", "tmp", "debug.log"); try (Stream<String> stream = Files.lines(path)) { stream.filter(line -> line.contains("ERROR")) .findFirst() .ifPresent(System.out::println); } catch (IOException ioe) { // handle the exception }
  • 64. @JosePaumard #50new8 I/O : lecture de fichiers texte Files.list retourne le contenu d’un répertoire // Java 7 : try with resources and use of Paths Path path = Paths.get("c:", "windows"); try (Stream<Path> stream = Files.list(path)) { stream.filter(path -> path.toFile().isDirectory()) .forEach(System.out::println); } catch (IOException ioe) { // handle the exception }
  • 65. @JosePaumard #50new8 I/O : lecture d’une arborescence Files.walk retourne le contenu d’un répertoire // Java 7 : try with resources and use of Paths Path path = Paths.get("c:", "windows"); try (Stream<Path> stream = Files.walk(path)) { stream.filter(path -> path.toFile().isDirectory()) .forEach(System.out::println); } catch (IOException ioe) { // handle the exception }
  • 66. @JosePaumard #50new8 I/O : lecture d’une arborescence Files.walk peut limiter la profondeur d’exploration // Java 7 : try with resources and use of Paths Path path = Paths.get("c:", "windows"); try (Stream<Path> stream = Files.walk(path, 2)) { stream.filter(path -> path.toFile().isDirectory()) .forEach(System.out::println); } catch (IOException ioe) { // handle the exception }
  • 67. List
  • 68. @JosePaumard #50new8 Iterable : forEach ForEach : permet de consommer les éléments Dommage : pas sur les tableaux // method forEach defined on Iterable List<String> strings = Arrays.asList("one", "two", "three") ; strings.forEach(System.out::println) ; > one, two, three
  • 69. @JosePaumard #50new8 Collection : removeIf Retire un objet à partir d’un prédicat Collection<String> strings = Arrays.asList("one", "two", "three", "four"); // works « in place », no Collections.unmodifiable... Collection<String> list = new ArrayList<>(strings); // returns true if the list has been modified boolean b = list.removeIf(s -> s.length() > 4); > one, two, four
  • 70. @JosePaumard #50new8 List : replaceAll Remplace un objet par sa transformation List<String> strings = Arrays.asList("one", "two", "three", "four"); // works « in place », no Collections.unmodifiable... List<String> list = new ArrayList<>(strings); // returns nothing list.replaceAll(String::toUpperCase); > ONE, TWO, THREE, FOUR
  • 71. @JosePaumard #50new8 List : sort Trie une liste « en place », à l’aide d’un Comparator List<String> strings = Arrays.asList("one", "two", "three", "four"); // works « in place », no Collections.unmodifiable... List<String> list = new ArrayList<>(strings); // returns nothing list.sort(Comparator.naturalOrder()) ; > four, one, three, two
  • 73. @JosePaumard #50new8 Comparator ! Que dire de mieux ? Comparator.naturalOrder() ;
  • 74. @JosePaumard #50new8 Comparator ! Que dire de mieux ? Comparator.naturalOrder() public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() { return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE; }
  • 75. @JosePaumard #50new8 Comparator ! enum NaturalOrderComparator implements Comparator<Comparable<Object>> { INSTANCE; // What is this??? }
  • 76. @JosePaumard #50new8 Comparator ! enum NaturalOrderComparator implements Comparator<Comparable<Object>> { INSTANCE; // OMG: a SINGLETON!!! } public class MySingleton { INSTANCE; private MySingleton() {} public static MySingleton getInstance() { // some buggy double-checked locking code return INSTANCE; } }
  • 77. @JosePaumard #50new8 Comparator ! enum NaturalOrderComparator implements Comparator<Comparable<Object>> { INSTANCE; public int compare(Comparable<Object> c1, Comparable<Object> c2) { return c1.compareTo(c2); } }
  • 78. @JosePaumard #50new8 Comparator ! enum NaturalOrderComparator implements Comparator<Comparable<Object>> { INSTANCE; public int compare(Comparable<Object> c1, Comparable<Object> c2) { return c1.compareTo(c2); } public Comparator<Comparable<Object>> reversed() { return Comparator.reverseOrder(); } }
  • 79. @JosePaumard #50new8 À l’ancienne ! Comparator ! // comparison using the last name Comparator<Person> compareLastName = new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.getLastName().compareTo(p2.getLastName()); } };
  • 80. @JosePaumard #50new8 Comparator ! // comparison using the last name then the first name Comparator<Person> compareLastNameThenFirstName = new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { int lastNameComparison = p1.getLastName().compareTo(p2.getLastName()); return lastNameComparison == 0 ? p2.getFirstName().compareTo(p2.getFirstName()); lastNameComparison; } };
  • 81. @JosePaumard #50new8 Comparator ! À la façon du JDK 8 ! Comparator.comparingBy(Person::getLastName); // static method
  • 82. @JosePaumard #50new8 Comparator ! À la façon du JDK 8 ! Comparator.comparingBy(Person::getLastName) // static method .thenComparing(Person::getFirstName); // default method
  • 83. @JosePaumard #50new8 Comparator ! À la façon du JDK 8 ! Comparator.comparingBy(Person::getLastName) // static method .thenComparing(Person::getFirstName) // default method .thenComparing(Person::getAge);
  • 84. @JosePaumard #50new8 Comparator ! Vous n’aimez pas l’ordre naturel ? Comparator<Person> comp = Comparator.naturalOrder(); Comparator<Person> reversedComp = Comparator.reversedOrder();
  • 85. @JosePaumard #50new8 Comparator ! Vous n’aimez pas l’ordre naturel ? Comparator<Person> comp = Comparator.comparingBy(Person::getLastName); Comparator<Person> reversedComp = comp.reversed();
  • 86. @JosePaumard #50new8 Comparator ! Et que fait-on pour les valeurs nulles ? Comparator<Person> comp = Comparator.naturalOrder();
  • 87. @JosePaumard #50new8 Comparator ! Et que fait-on pour les valeurs nulles ? Comparator<Person> comp = Comparator.nullsFirst(Comparator.naturalOrder());
  • 88. @JosePaumard #50new8 Comparator ! Et que fait-on pour les valeurs nulles ? Comparator<Person> comp = Comparator.nullsFirst(Comparator.naturalOrder()); Comparator<Person> comp = Comparator.nullsLast(Comparator.naturalOrder());
  • 90. @JosePaumard #50new8 Optional Optional a été créé pour indiquer qu’une méthode peut ne retourner « aucune valeur » Ex : max(), min()
  • 91. @JosePaumard #50new8 Optional Optional a été créé pour indiquer qu’une méthode peut ne retourner « aucune valeur » Ex : max(), min(), average()
  • 92. @JosePaumard #50new8 Optional Un Optional est un type enveloppe, qui peut être vide Comment peut-on en créer un ? Optional<String> opt = Optional.<String>empty() ; Optional<String> opt = Optional.of("one") ; // not null Optional<String> opt = Optional.ofNullable(s) ; // may be null
  • 93. @JosePaumard #50new8 Optional Un Optional est un type enveloppe, qui peut être vide Comment peut-on en créer un ? Optional<String> opt = ... ; if (opt.isPresent()) { String s = opt.get() ; } else { ... }
  • 94. @JosePaumard #50new8 Optional Un Optional est un type enveloppe, qui peut être vide Comment peut-on en créer un ? String s = opt.orElse("") ; // this is a default value that // is valid for our application Optional<String> opt = ... ; if (opt.isPresent()) { String s = opt.get() ; } else { ... }
  • 95. @JosePaumard #50new8 Optional Un Optional est un type enveloppe, qui peut être vide Comment peut-on en créer un ? String s = opt.orElseThrow(MyException::new) ; // lazy initialization
  • 96. @JosePaumard #50new8 Optional : patterns Un Optional peut aussi être vu comme un Stream comportant 0 ou 1 élément void ifPresent(Consumer<T> consumer) ;
  • 97. @JosePaumard #50new8 Optional : patterns Un Optional peut aussi être vu comme un Stream comportant 0 ou 1 élément void ifPresent(Consumer<T> consumer) ; Optional<T> filter(Predicate<T> mapper) ;
  • 98. @JosePaumard #50new8 Optional : patterns Un Optional peut aussi être vu comme un Stream comportant 0 ou 1 élément void ifPresent(Consumer<T> consumer) ; Optional<T> filter(Predicate<T> mapper) ; Optional<U> map(Function<T, U> mapper) ;
  • 99. @JosePaumard #50new8 Optional : patterns Un Optional peut aussi être vu comme un Stream comportant 0 ou 1 élément void ifPresent(Consumer<T> consumer) ; Optional<T> filter(Predicate<T> mapper) ; Optional<U> map(Function<T, U> mapper) ; Optional<U> flatMap(Function<T, Optional<U>> mapper) ;
  • 100. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! public class NewMath { public static Optional<Double> inv(Double d) { return d == 0.0d ? Optional.empty() : Optional.of(1/d) ; } public static Optional<Double> sqrt(Double d) { return d < 0.0d ? Optional.empty() : Optional.of(Math.sqrt(d)) ; } }
  • 101. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; List<Double> result = new ArrayList<>() ; doubles.forEach( d1 -> NewMath.inv(d1) // Optional<Double> .flatMap(d2 -> NewMath.sqrt(d2)) // Optional<Double> .ifPresent(result::add) ) ; doubles : [-1.0, 0.0, 1.0] result : [1.0]
  • 102. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; List<Double> result = new ArrayList<>() ; doubles.forEach( d1 -> NewMath.inv(d1) // Optional<Double> .flatMap(d2 -> NewMath.sqrt(d2)) // Optional<Double> .ifPresent(result::add) // Baaaaad pattern  ) ; doubles : [-1.0, 0.0, 1.0] result : [1.0]
  • 103. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; List<Double> result = new ArrayList<>() ; doubles.forEach( d1 -> NewMath.inv(d1) // Optional<Double> .flatMap(d2 -> NewMath.sqrt(d2)) // Optional<Double> .ifPresent(result::add) // Baaaaad pattern  ) ; doubles : [-1.0, 0.0, 1.0] result : [1.0]
  • 104. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! Function<Double, Optional<Double>> f = d -> NewMath.inv(d) // Optional<Double> .flatMap(d -> NewMath.sqrt(d))// Optional<Double>
  • 105. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! d -> NewMath.inv(d) // Optional<Double> .flatMap(NewMath::sqrt) // Optional<Double> .map(Stream::of) // Optional<Stream<Double>>
  • 106. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! d -> NewMath.inv(d) // Optional<Double> .flatMap(NewMath::sqrt) // Optional<Double> .map(Stream::of) // Optional<Stream<Double>> .orElse(Stream.empty()) // Stream<Double>
  • 107. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! Function<Double, Stream<Double>> f = d -> NewMath.inv(d) // Optional<Double> .flatMap(NewMath::sqrt) // Optional<Double> .map(Stream::of) // Optional<Stream<Double>> .orElse(Stream.empty()) ; // Stream<Double>
  • 108. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; doubles.stream() .flatMap( d -> NewMath.inv(d) // Optional<Double> .flatMap(NewMath::sqrt) // Optional<Double> .map(Stream::of) // Optional<Stream<Double>> .orElse(Stream.empty()) // Stream<Double> ) // Stream<Double>
  • 109. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; List<Double> result = doubles.stream() .flatMap( d -> NewMath.inv(d) // Optional<Double> .flatMap(NewMath::sqrt) // Optional<Double> .map(Stream::of) // Optional<Stream<Double>> .orElse(Stream.empty()) // Stream<Double> ) // Stream<Double> .collect(Collectors.toList()) ;
  • 110. @JosePaumard #50new8 Optional : nouveaux patterns en vue ! List<Double> doubles = Arrays.asList(-1d, 0d, 1d) ; List<Double> result = doubles.stream().parallel() .flatMap( d -> NewMath.inv(d) // Optional<Double> .flatMap(NewMath::sqrt) // Optional<Double> .map(Stream::of) // Optional<Stream<Double>> .orElse(Stream.empty()) // Stream<Double> ) // Stream<Double> .collect(Collectors.toList()) ;
  • 111. Map
  • 112. @JosePaumard #50new8 Map : forEach Prend un BiConsumer // the existing map Map<String, Person> map = ... ; map.forEach( (key, value) -> System.out.println(key + " -> " + value) ) ;
  • 113. @JosePaumard #50new8 Map : get Que se passe-t-il si la clé n’est pas dans la map ? // the existing map Map<String, Person> map = ... ; Person p = map.get(key);
  • 114. @JosePaumard #50new8 Map : get On peut retourner une valeur par défaut // the existing map Map<String, Person> map = ... ; Person p = map.getOrDefault(key, Person.DEFAULT_PERSON);
  • 115. @JosePaumard #50new8 Map : put Même idée pour le put // the existing map Map<String, Person> map = ... ; map.put(key, person);
  • 116. @JosePaumard #50new8 Map : putIfAbsent Même idée pour le put // the existing map Map<String, Person> map = ... ; map.put(key, person); map.putIfAbsent(key, person);
  • 117. @JosePaumard #50new8 Map : replace Même idée pour le replace // the existing map Map<String, Person> map = ... ; // key, newValue map.replace("six", john) ; // key, oldValue, newValue map.replace("six", peter, john) ;
  • 118. @JosePaumard #50new8 Map : replaceAll Permet de « remapper » une map avec une l // the existing map Map<String, Person> map = ... ; // key, oldValue map.replaceAll( (key, value) -> key + " -> " + value ; ) ;
  • 119. @JosePaumard #50new8 Map : remove Efface une paire clé / valeur si elle est la // the existing map Map<String, Person> map = ... ; // key, oldValue map.remove("six", john) ;
  • 120. @JosePaumard #50new8 Map : compute Calcule une valeur à partir d’une paire clé / valeur existante, et d’une l // the existing map Map<String, Person> map = ... ; // key, oldValue map.compute( key, (key, person) -> key + "::" + person // person can be null ) ;
  • 121. @JosePaumard #50new8 Map : computeIfAbsent Calcule une valeur à partir d’une clé si elle n’est pas dans la map // the existing map Map<String, Person> map = ... ; // key, no existing value map.computeIfAbsent( key, key -> person ) ;
  • 122. @JosePaumard #50new8 Map : computeIfPresent Calcule une valeur à partir d’une paire clé / valeur présente, et d’une l // the existing map Map<String, Person> map = ... ; // key, the existing value map.computeIfPresent( key, person, (key, person) -> newPerson // person cannot be null ) ;
  • 123. @JosePaumard #50new8 Map : compute* Le truc, c’est que ces méthodes retournent la valeur, qu’elle ait été juste créée ou pas
  • 124. @JosePaumard #50new8 Construire des maps de maps Construire des maps de maps devient un jeu d’enfant ! // the existing map Map<String, Map<String, Person>> map = ... ; // key, newValue map.computeIfAbsent( "one", (key) -> HashMap::new ).put("two", john);
  • 125. @JosePaumard #50new8 Map : merge Calcule une nouvelle valeur à partir de la paire clé / valeur existante, d’une valeur à ajouter, et d’une l // the existing map Map<Long, String> map = ... ; // key, otherValue map.merge( key, otherValue, (value, otherValue) -> String.join(", ", value, otherValue) ) ;
  • 127. @JosePaumard #50new8 Annotations en Java 7 Une annotation ne peut être posée qu’une fois Donc on crée des annotations enveloppe… @TestCases({ @TestCase(param=1, expected=false), @TestCase(param=2, expected=true) }) public boolean even(int param) { return param % 2 == 0; }
  • 128. @JosePaumard #50new8 Annotations en Java 8 Avec Java 8, on peut ! @TestCase(param=1, expected=false), @TestCase(param=2, expected=true) public boolean even(int param) { return param % 2 == 0; }
  • 129. @JosePaumard #50new8 Comment ça marche ? En fait, il y a un truc !
  • 130. @JosePaumard #50new8 Comment ça marche ? D’abord, on crée nos annotations comme avant @interface TestCase { int param(); boolean expected(); } @interface TestCases { TestCase[] value(); }
  • 131. @JosePaumard #50new8 Comment ça marche ? Et on ajoute @Repeatable @Repeatable(TestCases.class) @interface TestCase { int param(); boolean expected(); } @interface TestCases { TestCase[] value(); }
  • 132. @JosePaumard #50new8 Type annotations Les annotations peuvent être posées sur les types Exemple 1 : nous dit que persons ne peut pas être nul private @NonNull List<Person> persons = ... ;
  • 133. @JosePaumard #50new8 Type annotations Les annotations peuvent être posées sur les types Exemple 1 : nous dit que persons ne peut pas être nul Exemple 2 : la liste ne peut contenir des valeurs nulles private @NonNull List<Person> persons = ... ; private @NonNull List<@NonNull Person> persons = ... ;
  • 135. @JosePaumard #50new8 Parallel Arrays Arrays.parallelSetAll long [] array = new long [...] ; Arrays.parallelSetAll(array, index -> index % 3) ; System.out.println(Arrays.toString(array)) ;
  • 136. @JosePaumard #50new8 Parallel Arrays Arrays.parallelPrefix : fold right long [] array = new long [...] ; Arrays.parallelPrefix(array, (l1, l2) -> l1 + l2) ; System.out.println(Arrays.toString(array)) ; long [] array = {1L, 1L, 1L, 1L} ; > [1, 2, 3, 4]
  • 137. @JosePaumard #50new8 Parallel Arrays Arrays.parallelSort : tri « en place » long [] array = new long [...] ; Arrays.parallelSort(array) ; System.out.println(Arrays.toString(array)) ;
  • 139. @JosePaumard #50new8 CompletableFuture Implémente Future CompletableFuture<String> page = CompletableFuture.supplyAsync( ) ;
  • 140. @JosePaumard #50new8 CompletableFuture Implémente Future CompletableFuture<String> page = CompletableFuture.supplyAsync( () -> readWebPage(url) // returns String ) ;
  • 141. @JosePaumard #50new8 CompletableFuture On peut alors créer des pipelines CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenApply( content -> getImages(content) // returns a List<Image> ) ; // returns a CompletableFuture<List<Image>>
  • 142. @JosePaumard #50new8 CompletableFuture On peut alors créer des pipelines CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenApply( content -> getImages(content) // returns a List<Image> ) .thenAccept( images -> images.forEach(System.out::println) );
  • 143. @JosePaumard #50new8 CompletableFuture thenCompose() : permet de composer les choses CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenCompose( content -> getImages(content) // returns List<Image> )
  • 144. @JosePaumard #50new8 CompletableFuture allOf : termine quand tout les calculs sont faits (anyOf) CompletableFuture.allOf( CompletableFuture.supplyAsync( () -> readWebPage(url) ) .thenCompose(content -> getImages(content)) .thenApply(image -> writeToDisk(image)) ) .join() ;
  • 145. @JosePaumard #50new8 CompletableFuture thenCombine : combine plusieurs CF avec une l La l est appliquée au résultat des deux CF CompletableFuture cf1 = ... ; CompletableFuture cf2 = ... ; cf1.thenCombine(cf2, (b1, b2) -> b1 & b2) ; // can combine // the results of CFs
  • 146. @JosePaumard #50new8 CompletableFuture thenCombine : combine plusieurs CF avec une l La l est appliquée au résultat des deux CF On a aussi : thenAcceptBoth, runAfterBoth CompletableFuture cf1 = ... ; CompletableFuture cf2 = ... ; cf1.thenCombine(cf2, (b1, b2) -> b1 & b2) ; // can combine // the results of CFs
  • 147. @JosePaumard #50new8 CompletableFuture applyToEither : prend le premier résultat disponible CompletableFuture cf1 = ... ; CompletableFuture cf2 = ... ; cf1.applyToEither(cf2, (b) -> ...) ; // applies to the first // CF that returns
  • 148. @JosePaumard #50new8 CompletableFuture applyToEither : prend le premier résultat disponible acceptEither, runAfterEither CompletableFuture cf1 = ... ; CompletableFuture cf2 = ... ; cf1.applyToEither(cf2, (b) -> ...) ; // applies to the first // CF that returns
  • 150. @JosePaumard #50new8 Variables atomiques Java 5 : AtomicLong atomic = new AtomicLong() ; long l1 = atomic.incrementAndGet() ;
  • 151. @JosePaumard #50new8 Variables atomiques Java 8 nous amène : AtomicLong atomic = new AtomicLong() ; long l1 = atomic.incrementAndGet() ; long l2 = atomic.updateAndGet(l -> l*2 + 1) ;
  • 152. @JosePaumard #50new8 Variables atomiques Java 8 nous amène : AtomicLong atomic = new AtomicLong() ; long l1 = atomic.incrementAndGet() ; long l2 = atomic.updateAndGet(l -> l*2 + 1) ; long l3 = atomic.accumulateAndGet(12L, (l1, l2) -> l1 % l2) ;
  • 153. @JosePaumard #50new8 LongAdder Java 8 nous amène : LongAdder adder = new LongAdder() ; adder.increment() ; // in a thread adder.increment() ; // in a 2nd thread adder.increment() ; // in a 3rd thread long sum = adder.sum() ;
  • 154. @JosePaumard #50new8 LongAccumulator Idem, avec une l : LongAccumulator accu = new LongAccumulator((l1, l2) -> Long.max(l1, l2), 0L) ; accu.accumulate(value1) ; // in a thread accu.accumulate(value2) ; // in a 2nd thread accu.accumulate(value2) ; // in a 3rd thread long sum = accu.longValue() ;
  • 155. @JosePaumard #50new8 StampedLock Un lock normal, avec lecture optimiste long stamp = sl.writeLock() ; try { ... } finally { sl.unlockWrite(stamp) ; } long stamp = sl.readLock() ; try { ... } finally { sl.unlockRead(stamp) ; } StampedLock sl= new StampedLock() ;
  • 156. @JosePaumard #50new8 StampedLock Un lock normal, avec lecture optimiste Lecture / écriture exclusives, mais… long stamp = sl.writeLock() ; try { ... } finally { sl.unlockWrite(stamp) ; } long stamp = sl.readLock() ; try { ... } finally { sl.unlockRead(stamp) ; } StampedLock sl= new StampedLock() ;
  • 157. @JosePaumard #50new8 StampedLock Un lock normal, avec lecture optimiste StampedLock sl= new StampedLock() ; long stamp = sl.tryOptimisticRead() ; // here we read a variable that can be changed in another thread if (lock.validate(stamp)) { // the read was not concurrent } else { // another thread acquired a write lock }
  • 159. @JosePaumard #50new8 ConcurrentHashMap La vieille ConcurrentHashMap V7 a été retirée Thread safe Pas de lock ≠ ConcurrentHashMap V7 Des nouvelles méthodes (un paquet…)
  • 161. @JosePaumard #50new8 ConcurrentHashMap 6000 lignes de code 54 classes membre
  • 162. @JosePaumard #50new8 ConcurrentHashMap 6000 lignes de code 54 classes membre FYI : 58 classes dans tout java.util.concurrent
  • 163. @JosePaumard #50new8 ConcurrentHashMap 6000 lignes de code 54 classes membre FYI : 58 classes dans tout java.util.concurrent Nouveaux patterns !
  • 164. @JosePaumard #50new8 ConcurrentHashMap Ne jamais utiliser size() int count = map.size() ; // should not be used count = map.mappingCount() ; // new method
  • 165. @JosePaumard #50new8 ConcurrentHashMap Ne jamais utiliser size() int count = map.size() ; // should not be used long count = map.mappingCount() ; // new method
  • 166. @JosePaumard #50new8 ConcurrentHashMap Méthode search() search(), searchKey(), searchValue(), searchEntry() Retourne le 1er élément qui vérifie le prédicat ConcurrentHashMap<Integer, String> map = ... ; map.search(10L, (key, value) -> value.length() < key) ;
  • 167. @JosePaumard #50new8 ConcurrentHashMap Méthode search() search(), searchKey(), searchValue(), searchEntry() Retourne le 1er élément qui vérifie le prédicat ConcurrentHashMap<Integer, String> map = ... ; map.search(10L, (key, value) -> value.length() < key) ;
  • 168. @JosePaumard #50new8 ConcurrentHashMap Méthode search() Si la map contient plus de 10 éléments, la recherche aura lieu en parallèle ! ConcurrentHashMap<Integer, String> map = ... ; map.search(10L, (key, value) -> value.length() < key) ;
  • 169. @JosePaumard #50new8 ConcurrentHashMap Méthode search() Si la map contient plus de 10 éléments, la recherche aura lieu en parallèle ! On peut passer 0 ou Long.MAX_VALUE ConcurrentHashMap<Integer, String> map = ... ; map.search(10L, (key, value) -> value.length() < key) ;
  • 170. @JosePaumard #50new8 ConcurrentHashMap Méthode forEach() forEach(), forEachKey(), forEachEntries() ConcurrentHashMap<Integer, String> map = ... ; map.forEach(10L, (key, value) -> System.out.println(String.join(key, "->", value) ) ;
  • 171. @JosePaumard #50new8 ConcurrentHashMap Méthode de réduction reduce(), reduceKey(), reduceEntries() ConcurrentHashMap<Integer, String> map = ... ; map.reduce(10L, (key, value) -> value.getName(), // transformation (name1, name2) -> name1.length() > name2.length() ? name1 : name2) // reduction ) ;
  • 172. @JosePaumard #50new8 Pas de ConcurrentHashSet Mais… Set<String> set = ConcurrentHashMap.newKeySet() ;
  • 173. @JosePaumard #50new8 Pas de ConcurrentHashSet Mais… Crée une concurrent hashmap dans laquelle les valeurs sont Boolean.TRUE Se comporte donc comme un ConcurrentSet Set<String> set = ConcurrentHashMap.newKeySet() ;
  • 174.
  • 175.