KEMBAR78
Introduction to new features in java 8 | PDF
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_develope
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
Questions?Questions?

Introduction to new features in java 8

  • 1.
    Introduction toIntroduction to NewFeatures 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.
  • 2.
    Demonstration code at:.http://github.com/khatchad/java8-demo
  • 3.
    Some HistorySome History Javawas 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).
  • 4.
    Java 8 isMassiveJava 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.
  • 5.
    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.
  • 6.
    Lambda ExpressionsLambda Expressions Ablock 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.
  • 7.
    How are theydifferent from Java methods?
  • 8.
    LambdasLambdas (int x, inty) -> x + y () -> 42 (String s) -> {System.out.println(s);}
  • 9.
    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!"));
  • 10.
    LambdasLambdas ExamplesExamples List<String> strs =...; Collections.sort(strs, (s1, s2) -> Integer.compare(s1.length(), s2.length())); new Thread(() -> { connectToService(); sendNotification(); }).start();
  • 11.
  • 12.
    Functional InterfacesFunctional Interfaces ExampleExample @FunctionalInterface publicinterface Runnable { public void run(); } Runnable r = () -> System.out.println("Hello World!");
  • 13.
    java.util.functionjava.util.function Predicate<T> - aboolean-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
  • 14.
    Method ReferencesMethod References Treatingan existing method as an instance of a Functional Interface
  • 15.
    Method ReferencesMethod References ExamplesExamples classPerson { 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);
  • 16.
    Method ReferencesMethod References Kindsof 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)
  • 17.
    Method ReferencesMethod References MoreExamplesMore Examples Consumer<Integer> b1 = System::exit; Consumer<String[]> b2 = Arrays::sort; Consumer<String> b3 = MyProgram::main; Runnable r = MyProgram::main;
  • 18.
    Default MethodsDefault Methods Adddefault behaviours to interfaces
  • 19.
    Why default methods?Whydefault methods? Java 8 has lambda expressions. We want to start using them: List<?> list = ... list.forEach(...); // lambda code goes here
  • 20.
    There's a problemThere'sa problem The forEach method isn’t declared by java.util.List nor the java.util.Collection interface because doing so would break existing implementations.
  • 21.
    Default MethodsDefault Methods Wehave lambdas, but we can't force new behaviours into the current libraries. Solution: default methods.
  • 22.
    Default MethodsDefault Methods Traditionally,interfaces can't have method definitions (just declarations). Default methods supply default implementations of interface methods.
  • 23.
  • 24.
  • 25.
    public interface A{ default void foo() { System.out.println("Calling A.foo()"); } } public class Clazz implements A { }
  • 26.
    Client codeClient code Clazzclazz = new Clazz(); clazz.foo(); OutputOutput "Calling A.foo()"
  • 27.
    Example 2Example 2 GettingmessyGetting messy
  • 28.
    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?
  • 29.
    Of course not(Java is not C++)! class Clazz inherits defaults for foo() from both types A and B How do we fix it?
  • 30.
    Option A: public classClazz 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.
  • 31.
    Going back tothe example of forEach method, how can we force it's default implementation all the iterable collections?
  • 32.
    Let's take alook 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.
  • 33.
    We can findits 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); } } }
  • 34.
    The forEach methodtakes 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.
  • 35.
    SummarySummary Default methods canbe 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
  • 36.
  • 37.
    AccumulatorsAccumulators The continual evolutionof uses of concurrency and parallelism in applications requires continual evolution in library support. For this purpose, the Accumulators were introduced.
  • 38.
    AccumulatorsAccumulators Maintaining a singlecount, 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
  • 39.
    AccumulatorsAccumulators Package java.util.concurrent mechanismssynchronized 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.
  • 40.
    AccumulatorsAccumulators Both the DoubleAdderand 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).
  • 41.
  • 42.
    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
  • 43.
    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
  • 44.
  • 45.
    java.util.streamjava.util.stream List<Student> students =…; Stream stream = students.stream(); // sequential version // parallel version Stream parallelStream = students.parallelStream(); traversed once infinite lazy
  • 46.
    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);
  • 47.
    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
  • 48.
    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());
  • 49.
    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));
  • 50.
  • 51.
    java.timejava.time Current TimeCurrent Time ClockclockUTC = Clock.systemUTC(); Clock clockDefault = Clock.systemDefaultZone();
  • 52.
    java.timejava.time Time ZonesTime Zones ZoneIdzone = ZoneId.systemDefault(); ZoneId zoneBerlin = ZoneId.of("Europe/Berlin"); Clock clock = Clock.system(zoneBerlin);
  • 53.
    java.timejava.time Human Readable TimeHumanReadable 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());
  • 54.
    java.timejava.time Doing CalculationsDoing Calculations LocalTimelt = LocalTime.now(); lt.plus(5, ChronoUnit.HOURS); lt.plusHours(5); Duration dur = Duration.of(5, ChronoUnit.HOURS); lt.plus(dur);
  • 55.
    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_develope http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
  • 56.