SlideShare a Scribd company logo
@JosePaumard#50new8
50 new things we can do with Java 8
José Paumard
@JosePaumard
blog.paumard.org
@JosePaumard
new things we can do with
Java
50 new things we can do with Java 8
50 new things we can do with Java 8
50 new things we can do with Java 8
Questions?
#50new8
@JosePaumard
Date
@JosePaumard#50new8
Date: Instant
An Instant is a point on the time line
Instant start = Instant.now() ;
Instant end = Instant.now() ;
@JosePaumard#50new8
Date: Duration
A « duration » is the amount of time between instants
Instant start = Instant.now() ;
Instant end = Instant.now() ;
Duration elapsed = Duration.between(start, end) ;
long millis = elapsed.toMillis() ;
@JosePaumard#50new8
Date: Duration
There is an arithmetic on durations
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
The precision of the time line is 10-9 s (nanosecond)
@JosePaumard#50new8
Date: Duration
The precision of the time line is 10-9 s (nanosecond)
You think it’s high precision?
@JosePaumard#50new8
Date: Duration
The precision of the time line is 10-9 s (nanosecond)
You think it’s high precision?
Well the l of the
Higgs boson is 10-23 s
@JosePaumard#50new8
Date: LocalDate
A LocalDate is an « every day » date
LocalDate now = LocalDate.now() ;
LocalDate shakespeareDoB =
LocaleDate.of(1564, Month.APRIL, 23) ;
@JosePaumard#50new8
Date: Period
A « period » is the amount of time between local dates
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
A « period » is the amount of time between local dates
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
Arithmetic with local dates
LocalDate now = LocalDate.now() ;
LocalDate nextSunday =
now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
@JosePaumard#50new8
Date: TemporalAdjuster
Arithmetic with local dates
A toolbox of 14 static methods
firstDayOfMonth(), lastDayOfYear()
firstDayOfNextMonth()
LocalDate now = LocalDate.now() ;
LocalDate nextSunday =
now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
@JosePaumard#50new8
Date: TemporalAdjuster
Arithmetic with local dates
A toolbox of 14 static methods
firstInMonth(DayOfWeek.MONDAY)
next(DayOfWeek.FRIDAY)
LocalDate now = LocalDate.now() ;
LocalDate nextSunday =
now.with(TemporalAdjuster.next(DayOfWeek.SUNDAY)) ;
@JosePaumard#50new8
Date: LocalTime
A LocalTime is an everyday time: ex. 10:20
LocalTime now = LocalTime.now() ;
LocalTime time = LocalTime.of(10, 20) ; // 10:20
@JosePaumard#50new8
Date: LocalTime
A LocalTime is an everyday time: 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
Useful for localized times
Set<String> allZonesIds = ZoneId.getAvailableZoneIds() ;
String ukTZ = ZoneId.of("Europe/London") ;
@JosePaumard#50new8
Date: ZonedTime
Useful for localized times
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
Arithmetic on localized time
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
Arithmetic on localized time
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
Factory class: 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: bridges with java.util.Date
Factory class: DateTimeFormatter
Date date = Date.from(instant); // API -> legacy
Instant instant = date.toInstant(); // legacy -> new API
@JosePaumard#50new8
Date: bridges with java.util.Date
Factory class: DateTimeFormatter
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: bridges with java.util.Date
Factory class: DateTimeFormatter
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: bridges with java.util.Date
Factory class: DateTimeFormatter
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
Building a Stream on a String
Building a Stream on the letters of a String:
String s = "hello";
IntStream stream = s.chars(); // stream on the letters of s
@JosePaumard#50new8
Building a Stream on a String
Building a Stream on the letters of a 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
Building a Stream on a String
Building a Stream on the letters of a String:
String s = "hello";
IntStream stream = s.chars(); // stream on the letters of s
s.chars()
.map(Character::toUpperCase)
.forEach(System.out::println);
> HELLO7269767679
@JosePaumard#50new8
Building a Stream on a String
Building a Stream on the letters of a 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
Building a Stream on a String
Building a Stream on the letters of a 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: regular expressions
Building a Stream from a regexp
// book is a looooooooong String
Stream<String> words =
Pattern
.compile("[^p{javaLetter}]")
.splitAsStream(book) ;
@JosePaumard#50new8
String: concatenation
The newbie writes:
String s1 = "hello" ;
String s2 = " world!" ;
String s3 = s1 + " " + s2 ;
@JosePaumard#50new8
String: concatenation
The ignorant tells him to write:
StringBuffer sb1 = new StringBuffer("hello") ;
sb1.append(" world") ;
String s3 = sb1.toString() ;
(and is wrong)
@JosePaumard#50new8
String: concatenation
The seasonned dev tells him to write:
StringBuilder sb1 = new StringBuilder("hello") ;
sb1.append(" world") ;
String s3 = sb1.toString() ;
(and is wrong too…)
@JosePaumard#50new8
String: concatenation
Because the newbie is right (even if he doesn’t know)
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: concatenation
The Java 8 well-trained dev writes:
// 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: concatenation
The Java 8 well-trained dev writes:
And it prints:
// 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: concatenation
The Java 8 well-trained dev writes:
And it prints:
// The JDK 8 way
StringJoiner sj = new StringJoiner(", ") ;
sj.add("one") ;
String s = sj.toString() ;
System.out.println(s) ;
> one
@JosePaumard#50new8
String: concatenation
The Java 8 well-trained dev writes:
And it prints:
// 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: concatenation
The Java 8 well-trained dev writes:
And it prints:
// The JDK 8 way
StringJoiner sj = new StringJoiner(", ", "{", "}") ;
sj.add("one") ;
String s = sj.toString() ;
System.out.println(s) ;
> {one}
@JosePaumard#50new8
String: concatenation
The Java 8 well-trained dev writes:
And it prints:
// 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: concatenation
And it’s nearly accessible from the String class itself:
And it prints:
// From the String class, with a vararg
String s = String.join(", ", "one", "two", "three");
System.out.println(s);
> one, two, three
@JosePaumard#50new8
String: concatenation
And it’s nearly accessible from the String class itself:
And it prints:
// 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
Numbers: new methods
Method max, min, sum
// max method available on number wrapper classes
long max = Long.max(1L, 2L);
long sum = Long.sum(1L, 2L);
@JosePaumard#50new8
Numbers: new methods
Method max, min, sum
Is it really that useful?
// max method available on number wrapper classes
long max = Long.max(1L, 2L);
long sum = Long.sum(1L, 2L);
@JosePaumard#50new8
Numbers: new methods
Method max, min, sum
Is it really that useful?
// 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
Numbers: new methods
Method max, min, sum
Is it really that useful? Nice to write 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
Numbers: new methods
Method 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
Numbers: new methods
Method 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
Numbers: new methods
Hashcode computation
// JDK 7
long l = 3141592653589793238L;
int hash = new Long(l).hashCode(); // -1985256439
@JosePaumard#50new8
Numbers: new methods
Hashcode computation
// 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: reading text files
Stream extends 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: reading text files
Files.list returns the content of the directory
// 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: reading a tree of subdirs
Files.walk returns the content of the subtree
// 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: reading a tree of subdirs
Files.walk returns the content of the subtree, limit the depth
// 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: consumes the elements
Doesn’t work on arrays
// 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
Removes an object, takes a Predicate
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
Replaces an object with its transform
Collection<String> strings =
Arrays.asList("one", "two", "three", "four");
// works « in place », no Collections.unmodifiable...
Collection<String> list = new ArrayList<>(strings);
// returns nothing
list.replaceAll(String::toUpperCase);
> ONE, TWO, THREE, FOUR
@JosePaumard#50new8
List: sort
Sorts a List in place, takes a Comparator
Collection<String> strings =
Arrays.asList("one", "two", "three", "four");
// works « in place », no Collections.unmodifiable...
Collection<String> list = new ArrayList<>(strings);
// returns nothing
list.sort(Comparator.naturalOrder()) ;
> four, one, three, two
Comparator
@JosePaumard#50new8
Comparator!
What else?
Comparator.naturalOrder() ;
@JosePaumard#50new8
Comparator!
What else?
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
The good ol’ way!
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!
The JDK 8 way!
Comparator.comparingBy(Person::getLastName); // static method
@JosePaumard#50new8
Comparator!
The JDK 8 way!
Comparator.comparingBy(Person::getLastName) // static method
.thenComparing(Person::getFirstName); // default method
@JosePaumard#50new8
Comparator!
The JDK 8 way!
Comparator.comparingBy(Person::getLastName) // static method
.thenComparing(Person::getFirstName) // default method
.thenComparing(Person::getAge);
@JosePaumard#50new8
Comparator!
Dont like the natural order?
Comparator<Person> comp = Comparator.naturalOrder();
Comparator<Person> reversedComp = Comparator.reversedOrder();
@JosePaumard#50new8
Comparator!
Dont like the natural order?
Comparator<Person> comp = Comparator.comparingBy(Person::getLastName);
Comparator<Person> reversedComp = comp.reversed();
@JosePaumard#50new8
Comparator!
And what about null values?
Comparator<Person> comp =
Comparator.naturalOrder();
@JosePaumard#50new8
Comparator!
And what about null values?
Comparator<Person> comp =
Comparator.nullsFirst(Comparator.naturalOrder());
@JosePaumard#50new8
Comparator!
And what about null values?
Comparator<Person> comp =
Comparator.nullsFirst(Comparator.naturalOrder());
Comparator<Person> comp =
Comparator.nullsLast(Comparator.naturalOrder());
Map
@JosePaumard#50new8
Map: forEach
Takes a BiConsumer
// the existing map
Map<String, Person> map = ... ;
map.forEach(
(key, value) -> System.out.println(key + " -> " + value)
) ;
@JosePaumard#50new8
Map: get
What happens if key is not in the map?
// the existing map
Map<String, Person> map = ... ;
Person p = map.get(key);
@JosePaumard#50new8
Map: get
// the existing map
Map<String, Person> map = ... ;
Person p = map.getOrDefault(key, Person.DEFAULT_PERSON);
@JosePaumard#50new8
Map: put
// the existing map
Map<String, Person> map = ... ;
map.put(key, person);
@JosePaumard#50new8
Map: putIfAbsent
// the existing map
Map<String, Person> map = ... ;
map.put(key, person);
map.putIfAbsent(key, person);
@JosePaumard#50new8
Map: replace
Replaces a value from its key
// 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
Replaces all the values from the map, using a l
// the existing map
Map<String, Person> map = ... ;
// key, oldValue
map.replaceAll(
(key, value) -> key + " -> " + value ;
) ;
@JosePaumard#50new8
Map: remove
Removes a key / value pair if it’s there
// the existing map
Map<String, Person> map = ... ;
// key, oldValue
map.remove("six", john) ;
@JosePaumard#50new8
Map: compute
Computes a value from the existing key / value pair and a 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
Computes a value from a key that is not in the map
// the existing map
Map<String, Person> map = ... ;
// key, no existing value
map.computeIfAbsent(
key,
key -> person
) ;
@JosePaumard#50new8
Map: computeIfPresent
Computes a value from the existing key / value pair and a 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: merge
Computes the new value from the existing value, the newly
added value and a l
// the existing map
Map<String, Person> map = ... ;
// key, otherValue
map.merge(
key,
otherValue,
(value, otherValue) -> value.concat(", ").concat(otherValue)
) ;
@JosePaumard#50new8
Building bimaps
Making bimaps becomes sooo easy!
// the existing map
Map<String, Map<String, Person>> map = ... ;
// key, newValue
map.putIfAbsent(
"one",
(key) -> HashMap::new
).put("two", john);
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: in place sorting
long [] array = new long [...] ;
Arrays.parallelSort(array) ;
System.out.println(Arrays.toString(array)) ;
Completable
Future
@JosePaumard#50new8
CompletableFuture
Extension of Future
CompletableFuture<String> page =
CompletableFuture.supplyAsync(
) ;
@JosePaumard#50new8
CompletableFuture
Extension of Future
CompletableFuture<String> page =
CompletableFuture.supplyAsync(
() ->
readWebPage(url) // returns String
) ;
@JosePaumard#50new8
CompletableFuture
Now we can create pipelines
CompletableFuture.supplyAsync(
() ->
readWebPage(url)
)
.thenApply(
content -> getImages(content) // returns a List<Image>
) ; // returns a CompletableFuture<List<Image>>
@JosePaumard#50new8
CompletableFuture
Now we can create pipelines
CompletableFuture.supplyAsync(
() ->
readWebPage(url)
)
.thenApply(
content -> getImages(content) // returns a List<Image>
)
.thenAccept(
images -> images.forEach(System.out::println)
);
@JosePaumard#50new8
CompletableFuture
thenCompose(): does not wrap the result in a CF
CompletableFuture.supplyAsync(
() ->
readWebPage(url)
)
.thenCompose(
content -> getImages(content) // returns CF<List<Image>>
)
@JosePaumard#50new8
CompletableFuture
allOf: returns when all the tasks are done (see also anyOf)
CompletableFuture.allOf(
CompletableFuture.supplyAsync(
() ->
readWebPage(url)
)
.thenCompose(content -> getImages(content))
.thenApply(image -> writeToDisk(image))
)
.join() ;
@JosePaumard#50new8
CompletableFuture
thenCombine: can combine more than one CF
The l is applied once the two CF have completed
CompletableFuture cf1 = ... ;
CompletableFuture cf2 = ... ;
cf1.thenCombine(cf2, (b1, b2) -> b1 & b2) ; // can combine
// the results of CFs
@JosePaumard#50new8
CompletableFuture
thenCombine: can combine more than one CF
The l is applied once the two CF have completed
Also: thenAcceptBoth, runAfterBoth
CompletableFuture cf1 = ... ;
CompletableFuture cf2 = ... ;
cf1.thenCombine(cf2, (b1, b2) -> b1 & b2) ; // can combine
// the results of CFs
@JosePaumard#50new8
CompletableFuture
applyToEither: takes the first available result
CompletableFuture cf1 = ... ;
CompletableFuture cf2 = ... ;
cf1.applyToEither(cf2, (b) -> ...) ; // applies to the first
// CF that returns
@JosePaumard#50new8
CompletableFuture
applyToEither: takes the first available result
acceptEither, runAfterEither
CompletableFuture cf1 = ... ;
CompletableFuture cf2 = ... ;
cf1.applyToEither(cf2, (b) -> ...) ; // applies to the first
// CF that returns
Concurrence
@JosePaumard#50new8
Atomic variables
From Java 5:
AtomicLong atomic = new AtomicLong() ;
long l1 = atomic.incrementAndGet() ;
@JosePaumard#50new8
Atomic variables
Java 8 brings:
AtomicLong atomic = new AtomicLong() ;
long l1 = atomic.incrementAndGet() ;
long l2 = atomic.updateAndGet(l -> l*2 + 1) ;
@JosePaumard#50new8
Atomic variables
Java 8 brings:
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
From Java 8:
LongAdded 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
Same thing, with 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
A regular lock, with optimistic read
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
A regular lock, with optimistic read
Exclusive read / write, but…
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
A regular lock, with optimistic read
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
}
ConcurrentConcurrent
HashMap
@JosePaumard#50new8
ConcurrentHashMap
The old ConcurrentHashMap V7 has been removed
Thread safe
No locking ≠ ConcurrentHashMap V7
New methods (a lot…)
@JosePaumard#50new8
ConcurrentHashMap
6000 lines of code
@JosePaumard#50new8
ConcurrentHashMap
6000 lines of code
54 member classes
@JosePaumard#50new8
ConcurrentHashMap
6000 lines of code
54 member classes
FYI: 58 classes in java.util.concurrent
@JosePaumard#50new8
ConcurrentHashMap
6000 lines of code
54 member classes
FYI: 58 classes in java.util.concurrent
New patterns!
@JosePaumard#50new8
ConcurrentHashMap
Forget about size()
int count = map.size() ; // should not be used
count = map.mappingCount() ; // new method
@JosePaumard#50new8
ConcurrentHashMap
Forget about size()
int count = map.size() ; // should not be used
long count = map.mappingCount() ; // new method
@JosePaumard#50new8
ConcurrentHashMap
Search() method
search(), searchKey(), searchValue(), searchEntry()
Returns the 1st element that matches the predicate
ConcurrentHashMap<Integer, String> map = ... ;
map.search(10, (key, value) -> value.length() < key) ;
@JosePaumard#50new8
ConcurrentHashMap
Search() method
search(), searchKey(), searchValue(), searchEntry()
Returns the 1st element that matches the predicate
ConcurrentHashMap<Integer, String> map = ... ;
map.search(10, (key, value) -> value.length() < key) ;
@JosePaumard#50new8
ConcurrentHashMap
Search() method
If there are more than 10 elements, then the search will be
conducted in parallel!
ConcurrentHashMap<Integer, String> map = ... ;
map.search(10, (key, value) -> value.length() < key) ;
@JosePaumard#50new8
ConcurrentHashMap
Search() method
If there are more than 10 elements, then the search will be
conducted in parallel!
One can pass 0 or Long.MAX_VALUE
ConcurrentHashMap<Integer, String> map = ... ;
map.search(10, (key, value) -> value.length() < key) ;
@JosePaumard#50new8
ConcurrentHashMap
ForEach
forEach(), forEachKey(), forEachEntries()
ConcurrentHashMap<Integer, String> map = ... ;
map.forEach(10,
(key, value) ->
System.out.println(String.join(key, "->", value)
) ;
@JosePaumard#50new8
ConcurrentHashMap
Reduction
reduce(), reduceKey(), reduceEntries()
ConcurrentHashMap<Integer, String> map = ... ;
map.reduce(10,
(key, value) -> value.getName(), // transformation
(name1, name2) -> name1.length() > name2.length() ?
name1 : name2) // reduction
) ;
@JosePaumard#50new8
No ConcurrentHashSet
But…
Set<String> set = ConcurrentHashMap.newKeySet() ;
@JosePaumard#50new8
No ConcurrentHashSet
But…
Creates a concurrent hashmap in which the values are
Boolean.TRUE
Acts as a concurrent set
Set<String> set = ConcurrentHashMap.newKeySet() ;
50 new things we can do with Java 8
Thank you!
@JosePaumard
#50new8

More Related Content

PDF
Lambda and Stream Master class - part 1
PPTX
JFokus 50 new things with java 8
PDF
Java SE 8 for Java EE developers
PDF
Asynchronous API in Java8, how to use CompletableFuture
PDF
Free your lambdas
PDF
Java SE 8 for Java EE developers
PDF
JDK8 : parallel programming made (too ?) easy
PDF
Java 8, Streams & Collectors, patterns, performances and parallelization
Lambda and Stream Master class - part 1
JFokus 50 new things with java 8
Java SE 8 for Java EE developers
Asynchronous API in Java8, how to use CompletableFuture
Free your lambdas
Java SE 8 for Java EE developers
JDK8 : parallel programming made (too ?) easy
Java 8, Streams & Collectors, patterns, performances and parallelization

What's hot (20)

PDF
Lambdas and Streams Master Class Part 2
PDF
Java Full Throttle
PDF
Asynchronous programming done right - Node.js
ODP
Java Boilerplate Busters
PDF
The algebra of library design
PDF
Voxxed Days Vilnius 2015 - Having fun with Javassist
PDF
Callbacks, promises, generators - asynchronous javascript
ODP
Ast transformations
PDF
Leveraging Completable Futures to handle your query results Asynchrhonously
ODP
AST Transformations
PPTX
Building native Android applications with Mirah and Pindah
PDF
A deep dive into PEP-3156 and the new asyncio module
KEY
DjangoCon US 2011 - Monkeying around at New Relic
PPTX
Avoiding Callback Hell with Async.js
PDF
Understanding Asynchronous JavaScript
PDF
Oredev 2015 - Taming Java Agents
PDF
Riga Dev Day 2016 - Having fun with Javassist
PDF
JavaOne 2015 - Having fun with Javassist
PDF
Java9 Beyond Modularity - Java 9 más allá de la modularidad
PPTX
The Promised Land (in Angular)
Lambdas and Streams Master Class Part 2
Java Full Throttle
Asynchronous programming done right - Node.js
Java Boilerplate Busters
The algebra of library design
Voxxed Days Vilnius 2015 - Having fun with Javassist
Callbacks, promises, generators - asynchronous javascript
Ast transformations
Leveraging Completable Futures to handle your query results Asynchrhonously
AST Transformations
Building native Android applications with Mirah and Pindah
A deep dive into PEP-3156 and the new asyncio module
DjangoCon US 2011 - Monkeying around at New Relic
Avoiding Callback Hell with Async.js
Understanding Asynchronous JavaScript
Oredev 2015 - Taming Java Agents
Riga Dev Day 2016 - Having fun with Javassist
JavaOne 2015 - Having fun with Javassist
Java9 Beyond Modularity - Java 9 más allá de la modularidad
The Promised Land (in Angular)
Ad

Viewers also liked (20)

PDF
Linked to ArrayList: the full story
PDF
ArrayList et LinkedList sont dans un bateau
PDF
Free your lambdas
PDF
50 nouvelles choses que l'on peut faire avec Java 8
PDF
Autumn collection JavaOne 2014
PDF
50 nouvelles choses que l'on peut faire en Java 8
PDF
Going reactive in java
PDF
Java 8 Stream API and RxJava Comparison
PDF
Déploiement d'une application Java EE dans Azure
PDF
Java 8-streams-collectors-patterns
PPT
HighLoad++ 2009 In-Memory Data Grids
PDF
Phoenix for Rubyists
PPTX
Hazelcast and MongoDB at Cloud CMS
PDF
Async Gateway или Разработка системы распределенных вычислений с нуля
PDF
API Asynchrones en Java 8
PDF
Алексей Николаенков, Devexperts
PDF
Amazon cloud – готовим вместе
PDF
Hazelcast for Terracotta Users
PPTX
Code review at large scale
PDF
ЖК Зорге 9
Linked to ArrayList: the full story
ArrayList et LinkedList sont dans un bateau
Free your lambdas
50 nouvelles choses que l'on peut faire avec Java 8
Autumn collection JavaOne 2014
50 nouvelles choses que l'on peut faire en Java 8
Going reactive in java
Java 8 Stream API and RxJava Comparison
Déploiement d'une application Java EE dans Azure
Java 8-streams-collectors-patterns
HighLoad++ 2009 In-Memory Data Grids
Phoenix for Rubyists
Hazelcast and MongoDB at Cloud CMS
Async Gateway или Разработка системы распределенных вычислений с нуля
API Asynchrones en Java 8
Алексей Николаенков, Devexperts
Amazon cloud – готовим вместе
Hazelcast for Terracotta Users
Code review at large scale
ЖК Зорге 9
Ad

Similar to 50 new things we can do with Java 8 (20)

PDF
PPTX
JSR 310. New Date API in Java 8
PPTX
05 Java Language And OOP Part V
PPTX
Date time java 8 (jsr 310)
PPTX
Java 8
PDF
Introduction to Date and Time API 3
PDF
New Java Date/Time API
ODP
Hello Java 8
PDF
Java 8 date & time
PDF
Java 8 Stream API. A different way to process collections.
PPTX
Basic java, java collection Framework and Date Time API
PPTX
U-III Prt-2.pptx0 for Java and hardware coding...
PDF
Introduction to Date and Time API 3
PPTX
Java 8 Examples
PDF
JDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go Wrong
PPT
PDF
M251_Meeting 2_updated_2.pdf(M251_Meeting 2_updated_2.pdf)
PPTX
Java22_1670144363.pptx
PPTX
[Java] #8 String and Inner Class
PPTX
java150929145120-lva1-app6892 (2).pptx
JSR 310. New Date API in Java 8
05 Java Language And OOP Part V
Date time java 8 (jsr 310)
Java 8
Introduction to Date and Time API 3
New Java Date/Time API
Hello Java 8
Java 8 date & time
Java 8 Stream API. A different way to process collections.
Basic java, java collection Framework and Date Time API
U-III Prt-2.pptx0 for Java and hardware coding...
Introduction to Date and Time API 3
Java 8 Examples
JDD 2016 - Grzegorz Rozniecki - Java 8 What Could Possibly Go Wrong
M251_Meeting 2_updated_2.pdf(M251_Meeting 2_updated_2.pdf)
Java22_1670144363.pptx
[Java] #8 String and Inner Class
java150929145120-lva1-app6892 (2).pptx

More from José Paumard (17)

PDF
Loom Virtual Threads in the JDK 19
PDF
From Java 11 to 17 and beyond.pdf
PDF
The Future of Java: Records, Sealed Classes and Pattern Matching
PDF
Deep Dive Java 17 Devoxx UK
PDF
Designing functional and fluent API: application to some GoF patterns
PDF
The Sincerest Form of Flattery
PPTX
The Sincerest Form of Flattery
PDF
Designing functional and fluent API: example of the Visitor Pattern
PDF
Construire son JDK en 10 étapes
PDF
Java Keeps Throttling Up!
PDF
Asynchronous Systems with Fn Flow
PDF
JAX-RS and CDI Bike the (Reactive) Bridge
PDF
Collectors in the Wild
PDF
Streams in the wild
PDF
JAX RS and CDI bike the reactive bridge
PDF
L'API Collector dans tous ses états
PDF
Java 8 Streams and Rx Java Comparison
Loom Virtual Threads in the JDK 19
From Java 11 to 17 and beyond.pdf
The Future of Java: Records, Sealed Classes and Pattern Matching
Deep Dive Java 17 Devoxx UK
Designing functional and fluent API: application to some GoF patterns
The Sincerest Form of Flattery
The Sincerest Form of Flattery
Designing functional and fluent API: example of the Visitor Pattern
Construire son JDK en 10 étapes
Java Keeps Throttling Up!
Asynchronous Systems with Fn Flow
JAX-RS and CDI Bike the (Reactive) Bridge
Collectors in the Wild
Streams in the wild
JAX RS and CDI bike the reactive bridge
L'API Collector dans tous ses états
Java 8 Streams and Rx Java Comparison

Recently uploaded (20)

PDF
TR - Agricultural Crops Production NC III.pdf
PDF
O5-L3 Freight Transport Ops (International) V1.pdf
PDF
Module 4: Burden of Disease Tutorial Slides S2 2025
PPTX
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
PDF
BÀI TẬP BỔ TRỢ 4 KỸ NĂNG TIẾNG ANH 9 GLOBAL SUCCESS - CẢ NĂM - BÁM SÁT FORM Đ...
PDF
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
PDF
Basic Mud Logging Guide for educational purpose
PDF
Pre independence Education in Inndia.pdf
PDF
3rd Neelam Sanjeevareddy Memorial Lecture.pdf
PPTX
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
PDF
Anesthesia in Laparoscopic Surgery in India
PPTX
Cell Types and Its function , kingdom of life
PDF
STATICS OF THE RIGID BODIES Hibbelers.pdf
PDF
Supply Chain Operations Speaking Notes -ICLT Program
PDF
Complications of Minimal Access Surgery at WLH
PDF
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
PDF
01-Introduction-to-Information-Management.pdf
PDF
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
PDF
Sports Quiz easy sports quiz sports quiz
PPTX
Microbial diseases, their pathogenesis and prophylaxis
TR - Agricultural Crops Production NC III.pdf
O5-L3 Freight Transport Ops (International) V1.pdf
Module 4: Burden of Disease Tutorial Slides S2 2025
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
BÀI TẬP BỔ TRỢ 4 KỸ NĂNG TIẾNG ANH 9 GLOBAL SUCCESS - CẢ NĂM - BÁM SÁT FORM Đ...
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
Basic Mud Logging Guide for educational purpose
Pre independence Education in Inndia.pdf
3rd Neelam Sanjeevareddy Memorial Lecture.pdf
PPT- ENG7_QUARTER1_LESSON1_WEEK1. IMAGERY -DESCRIPTIONS pptx.pptx
Anesthesia in Laparoscopic Surgery in India
Cell Types and Its function , kingdom of life
STATICS OF THE RIGID BODIES Hibbelers.pdf
Supply Chain Operations Speaking Notes -ICLT Program
Complications of Minimal Access Surgery at WLH
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
01-Introduction-to-Information-Management.pdf
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
Sports Quiz easy sports quiz sports quiz
Microbial diseases, their pathogenesis and prophylaxis

50 new things we can do with Java 8