Introduction to new features in java 8

cstcolloquium 957 views 56 slides Mar 26, 2015
Slide 1
Slide 1 of 56
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56

About This Presentation

Java 8 is one of the largest upgrades to the popular language and framework in over a decade. This talk will detail several new key features of Java 8 that can help make programs easier to read, write, and maintain. Java 8 comes with many features, especially related to collection libraries. We will...


Slide Content

Introduction toIntroduction to
New Features inNew Features in
Java 8Java 8
Raffi Khatchadourian
Department of Computer Systems Technology
New York City College of Technology
City University of New York
Computer Systems Technology Colloquium
March 26, 2015
Based on slides by Duarte Duarte, Eduardo Martins, Miguel Marques and
Ruben Cordeiro and Horstmann, Cay S. (2014-01-10). Java SE8 for the
Really Impatient: A Short Course on the Basics (Java Series). Pearson
Education.

Demonstration code at: .http://github.com/khatchad/java8-demo

Some HistorySome History
Java was invented in the 90's as an Object-Oriented language.
Largest change was in ~2005 with Java 5.
Generics.
Enhanced for loops.
Annotations.
Type-safe enumerations.
Concurrency enhancements (AtomicInteger).

Java 8 is MassiveJava 8 is Massive
10 years later, Java 8 is packed with new features.
Core changes are to incorporate functional language features.
We can't cover everything today.
Will focus on some of the more distributive features.

Functional LanguagesFunctional Languages
Declarative ("what not how").
The only state is held in parameters.
Traditionally popular in academia and AI.
Well-suited for event-driven/concurrent ("reactive") programs.

Lambda ExpressionsLambda Expressions
A block of code that you can pass around so it can be
executed later, once or multiple times.
Anonymous methods.
Reduce verbosity caused by anonymous classes.

How are they different from Java methods?

LambdasLambdas
(int x, int y) -> x + y
() -> 42
(String s) -> {System.out.println(s);}

LambdasLambdas
ExamplesExamples
BeforeBefore
Button btn = new Button();
final PrintStream pStream = ...;
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
pStream.println("Button Clicked!");
}
});
AfterAfter
Button btn = new Button();
final PrintStream pStream = ...;
btn.setOnAction(e -> pStream.println( "Button Clicked!"));

LambdasLambdas
ExamplesExamples
List<String> strs = ...;
Collections.sort(strs, (s1, s2) ->
Integer.compare(s1.length(), s2.length()));
new Thread(() -> {
connectToService();
sendNotification();
}).start();

Functional InterfacesFunctional Interfaces
Single Abstract Method Type

Functional InterfacesFunctional Interfaces
ExampleExample
@FunctionalInterface
public interface Runnable {
public void run();
}
Runnable r = () -> System.out.println( "Hello World!");

java.util.functionjava.util.function
Predicate<T> - a boolean-valued property of an object
Consumer<T> - an action to be performed on an object
Function<T,R> - a function transforming a T to a R
Supplier<T> - provide an instance of a T (such as a factory)
UnaryOperator<T> - a function from T to T
BinaryOperator<T> - a function from (T,T) to T

Method ReferencesMethod References
Treating an existing method as an instance of a
Functional Interface

Method ReferencesMethod References
ExamplesExamples
class Person {
private String name;
private int age;
public int getAge() {return this.age;}
public String getName() {return this.name;}
}
Person[] people = ...;
Comparator<Person> byName = Comparator.comparing(Person::getName);
Arrays.sort(people, byName);

Method ReferencesMethod References
Kinds of method referencesKinds of method references
A static method (ClassName::methName)
An instance method of a particular object
(instanceRef::methName)
A super method of a particular object (super::methName)
An instance method of an arbitrary object of a particular type
(ClassName::methName)
A class constructor reference (ClassName::new)
An array constructor reference (TypeName[]::new)

Method ReferencesMethod References
More ExamplesMore Examples
Consumer<Integer> b1 = System::exit;
Consumer<String[]> b2 = Arrays::sort;
Consumer<String> b3 = MyProgram::main;
Runnable r = MyProgram::main;

Default MethodsDefault Methods
Add default behaviours to interfaces

Why default methods?Why default methods?
Java 8 has lambda expressions. We want to start using them:
List<?> list = ...
list.forEach(...); // lambda code goes here

There's a problemThere's a problem
The forEach method isn’t declared by java.util.List nor the
java.util.Collection interface because doing so would break
existing implementations.

Default MethodsDefault Methods
We have lambdas, but we can't force new behaviours into the current
libraries.
Solution: default methods.

Default MethodsDefault Methods
Traditionally, interfaces can't have method definitions (just
declarations).
Default methods supply default implementations of interface
methods.

ExamplesExamples

Example 1Example 1
BasicsBasics

public interface A {
default void foo() {
System.out.println("Calling A.foo()");
}
}
public class Clazz implements A {
}

Client codeClient code
Clazz clazz = new Clazz();
clazz.foo();
OutputOutput
"Calling A.foo()"

Example 2Example 2
Getting messyGetting messy

public interface A {
default void foo(){
System.out.println("Calling A.foo()");
}
}
public interface B {
default void foo(){
System.out.println("Calling B.foo()");
}
}
public class Clazz implements A, B {
}
Does this code compile?

Of course not (Java is not C++)!
class Clazz inherits defaults for foo() from both types
A and B
How do we fix it?

Option A:
public class Clazz implements A, B {
public void foo(){/* ... */}
}
We resolve it manually by overriding the conflicting method.
Option B:
public class Clazz implements A, B {
public void foo(){
A.super.foo(); // or B.super.foo()
}
}
We call the default implementation of method foo() from either
interface A or B instead of implementing our own.

Going back to the example of forEach method, how can we force it's
default implementation all the iterable collections?

Let's take a look at the Java UML for all the iterable Collections:
In order to add a default behaviour to all the iterable collections, a
default forEach method was added to the Iterable<E> interface.

We can find its default implementation in java.lang.Iterable
interface:
@FunctionalInterface
public interface Iterable {
Iterator iterator();
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
}

The forEach method takes a java.util.function.Consumer
functional interface type as a parameter, which enables us to pass in a
lambda or a method reference as follows:
List<?> list = ...
list.forEach(System.out::println);
This is also valid for Sets and Queues, for example, since both classes
implement the Iterable interface.

SummarySummary
Default methods can be seen as a bridge between lambdas and JDK
libraries.
Can be used in interfaces to provide default implementations of
otherwise abstract methods.
Clients can optionally implement (override) them.
static methods are now also allowed in interfaces.
Can eliminate the need for utility classes like .Collections

AccumulatorsAccumulators
Scalable updatable variables

AccumulatorsAccumulators
The continual evolution of uses of concurrency and parallelism in
applications requires continual evolution in library support. For this
purpose, the Accumulators were introduced.

AccumulatorsAccumulators
Maintaining a single count, sum, etc., that is updated by possibly many
threads is a common scalability problem.
A set of new classes were created for that purpose:
DoubleAccumulator
DoubleAdder
LongAccumulator
LongAdder

AccumulatorsAccumulators
Package java.util.concurrent mechanisms synchronized
operations between threads, however if all you want to do is increment
a variable across threads, it was overkill and then some.
These classes are usually preferable to alternatives when multiple
threads update a common value that is used for purposes such as
summary statistics that are frequently updated but less frequently read.

AccumulatorsAccumulators
Both the DoubleAdder and LongAdder classes can be seen as specific
subsets of the DoubleAccumulator and LongAccumulator
functionality.
The call new DoubleAdder() is equivalent to:
new DoubleAccumulator((x, y) -> x + y, 0.0) .
The call new LongAdder() is equivalent to:
new LongAccumulator((x, y) -> x + y, 0L) .

ExamplesExamples

DoubleAccumulator da = new DoubleAccumulator((x,y) -> x + y, 0.0);
List<Double> doubles = Arrays.asList( 1.0, 2.0, 3.0, 4.0, 10.0);
doubles.forEach(da::accumulate);
System.out.println("Result: " + da.doubleValue());
Output:
Result: 20

LongAdder la = new LongAdder() ;
List<Long> longs = Arrays.asList(10L, 20L, 30L, 40L, 100L);
longs.forEach(la::add);
System.out.println("Result: " + la.longValue());
Output:
Result: 200

java.util.streamjava.util.stream
filter/map/reduce for Java

java.util.streamjava.util.stream
List<Student> students = …;
Stream stream = students.stream(); // sequential version
// parallel version
Stream parallelStream = students.parallelStream();
traversed once
infinite
lazy

java.util.streamjava.util.stream
Stream sourcesStream sources
CollectionsCollections
Set<Student> set = new LinkedHashSet<>();
Stream<Student> stream = set.stream();
GeneratorsGenerators
Random random = new Random();
Stream<Integer> randomNumbers = Stream.generate(random::nextInt);
From other streamsFrom other streams
Stream newStream = Stream.concat(stream, randomNumbers);

java.util.streamjava.util.stream
Intermediate operationsIntermediate operations
.filter - excludes all elements that don’t match a Predicate
.map - perform transformation of elements using a Function
.flatMap - transform each element into zero or more elements by
way of another Stream
.peek - performs some action on each element
.distinct - excludes all duplicate elements (equals())
.sorted - orderered elements (Comparator)
.limit - maximum number of elements
.substream - range (by index) of elements
List<Person> persons = ...;
Stream<Person> tenPersonsOver18 = persons.stream()
.filter(p -> p.getAge() > 18)
.limit( 10);
More examples at: .https://github.com/cst2301-pt13/library-solution

java.util.streamjava.util.stream
Terminating operationsTerminating operations
1. Obtain a stream from some sources
2. Perform one or more intermidate operations
3. Perform one terminal operation
reducers like reduce(), count(), findAny(), findFirst()
collectors (collect())
forEach
iterators
List<Person> persons = ..;
List<Student> students = persons.stream()
.filter(p -> p.getAge() > 18)
.map(Student:: new)
.collect(Collectors.toList());

java.util.streamjava.util.stream
Parallel & SequentialParallel & Sequential
List<Person> persons = ..;
List<Student> students = persons.stream()
.parallel()
.filter(p -> p.getAge() > 18)
.sequential()
.map(Student::new)
.collect(Collectors.toCollection(ArrayList:: new));

java.timejava.time
Yet Another Java Date/Time API

java.timejava.time
Current TimeCurrent Time
Clock clockUTC = Clock.systemUTC();
Clock clockDefault = Clock.systemDefaultZone();

java.timejava.time
Time ZonesTime Zones
ZoneId zone = ZoneId.systemDefault();
ZoneId zoneBerlin = ZoneId.of( "Europe/Berlin");
Clock clock = Clock.system(zoneBerlin);

java.timejava.time
Human Readable TimeHuman Readable Time
class LocalDate {
public static LocalDate now() { ... }
public static LocalDate now(ZoneId zone) { ... }
public static LocalDate now(Clock clock) { ... }
}
LocalDate date = LocalDate.now();
System.out.printf("%s-%s-%s",
date.getYear(), date.getMonthValue(), date.getDayOfMonth());

java.timejava.time
Doing CalculationsDoing Calculations
LocalTime lt = LocalTime.now();
lt.plus(5, ChronoUnit.HOURS);
lt.plusHours(5);
Duration dur = Duration.of(5, ChronoUnit.HOURS);
lt.plus(dur);

Documentation & InterestingDocumentation & Interesting
LinksLinks
http://download.java.net/jdk8/docs/
http://download.java.net/jdk8/docs/api/
https://blogs.oracle.com/thejavatutorials/entry/jdk_8_documentation_developer_preview
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

Questions?Questions?