Agenda
• Environment lab
• Lambda expressions and Method references
• Functional Interfaces and Default Methods
• Java.util.function
• Stream API
• Repeating and Type Annotations
• New Java Date/Time API
• Java API additions
• Nashorn JS Engine
• Other stuffs
Environment lab
• Download JDK8 (currently 1.8.0-b132)
http://www.oracle.com/technetwork/java/javase/downloads/index.html
• IDE Support for JDK 8
– Eclipse 4.4 Luna (M6 partially compliant)
– NetBeans 8
– IntelliJ IDEA 13.1
• Java™ Platform, Standard Edition 8
API Specification
– http://docs.oracle.com/javase/8/docs/api/
Lambda expressions
• A lambda expression is an anonymous
function (not 100% true for Java but lets
assume it for time being)
• Syntax:
(arguments) -> (body)
• Following are some examples of Lambda
expressions:
(int a, int b) -> { return a + b; }
() -> System.out.println("Hello World");
(String s) -> { System.out.println(s); }
() -> 42
() -> { return 3.1415; };
Lambda expressions
• Four important syntax rules:
1. Declaring the types of the parameters is optional;
2. Using parentheses around the parameter is optional if
you have only one parameter;
3. Using curly braces is optional (unless you need multiple
statements);
4. The return keyword is optional if you have a single
expression that returns a value.
Lambda expressions
• Lambdas expressions are classified
into two types:
– Capturing
• Lambdas are said to be “capturing” if they access a
non-static variable or object that was defined outside
of the lambda body. For example, this lambda
captures the variable x:
int x = 5;
return y -> x + y;
Lambda expressions
• In order for this lambda
declaration to be valid, the variables
it captures must be “effectively final”.
So, either they must be marked with
the final modifier, or they must not be modified after
they're assigned.
– Non-capturing
• Is as opposed to capturing lambdas. A non-capturing lambda is
generally going to be more efficient than a capturing one,
because a non-capturing lambda only needs to be evaluated
once.
Lambda expressions
• What lambdas don't do?
– Non-final variable capture: If a variable is assigned a new
value, it can't be used within a lambda. The “final” keyword is not
required, but the variable must be “effectively final”. This code does
not compile:
int count = 0;
List<String> strings = Arrays.asList("a","b","c");
strings.forEach(s -> {
count++; // error: can't modify the value of count
});
Lambda expressions
– Exception transparency : If a checked exception may be
thrown from inside a lambda, the functional interface must also declare
that checked exception can be thrown. The exception is not propagated
to the containing method. This code does not compile:
void appendAll(Iterable<String> values, Appendable out)
throws IOException { // doesn't help with the error
values.forEach(s -> {
out.append(s); // error: can't throw IOException here
// Consumer.accept(T) doesn't allow it
});
}
There are ways to work around this:
– define your own functional interface that extends Consumer and wrap the
IOException through as a RuntimeException. (UncheckedIOException)
Lambda expressions
– Control flow (break, early return) :
In the forEach examples above, a traditional continue is possible
by placing a “return;” statement within the lambda. However, there
is no way to break out of the loop or return a value as the result of
the containing method from within the lambda. For example:
final String secret = "foo";
boolean containsSecret(Iterable<String> values) {
values.forEach(s -> {
if (secret.equals(s)) {
??? // want to end the loop and return true, but can't
}
});
}
Lambda expressions
– Examples:
//Old way:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello from thread");
}
}).start();
//New way:
new Thread(
() -> System.out.println("Hello from thread")
).start();
Lambda expressions
– Examples:
//Old way:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
for (Integer n : list) {
System.out.println(n);
}
//New way:
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
list.forEach(n -> System.out.println(n));
//or we can use :: double colon operator
list.forEach(System.out::println);
Lambda expressions
• Is a literal method value that uses the colon
double operator (::), corresponding to a
lambda expression:
Method references
• Method references can point to:
– Static methods; String::valueOf
– Instance methods; Object::toString
– Methods on instances; x::toString
– Constructors; TreeSet::new
Method references
Method reference Equivalent lambda expression
String::valueOf x -> String.valueOf(x)
Object::toString x -> x.toString()
x::toString () -> x.toString()
ArrayList::new () -> new ArrayList<>()
• Example:
List<String> words = Arrays.asList("Biga", "Pisca", “Lopam");
words.forEach(System.out::println);
// java.lang.Iterable:
default void forEach(Consumer<? super T> action)
//java.io.PrintStream:
public void println(String x)
Method references
Functional Interfaces
• a functional interface is defined as an
interface with exactly one
(non default) method.
• Example:
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Functional Interfaces
• A new annotation, @FunctionalInterface, has
been introduced.
• It can be placed on an interface to declare
the intention of it being a functional
interface.
• It will cause the interface to refuse to compile
unless you've managed to make it a
functional interface.
Functional Interfaces
• Each lambda expression can be implicitly
assigned to one of the interface called
Functional interface.
• Examples:
new Thread(
() -> System.out.println("hello world")
).start();
Comparator<String> c = (a, b) ->
Integer.compare(a.length(), b.length());
Default methods
• Default methods are not abstract, so a
functional interface can define as many
default methods as it likes.
• Why we need Default Methods?
– R: Extensibility without breaking the implementor
class.
Default methods
• Example:
public interface Iterable<T> {
Iterator<T> iterator();
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
Static methods on Interface
• Although not strictly related to default methods,
the ability to add static methods to interfaces is
a major change to the Java language.
public interface Stream<T> extends BaseStream<T, Stream<T>> {
...
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
...
}
java.util.function
• Java 8 comes with several functional interfaces in
package, java.util.function:
– Function<T,R> - takes an object of type T and returns R;
– Supplier<T> - just returns an object of type T;
– Predicate<T> - returns a boolean value based on input of type T;
– Consumer<T> - performs an action with given object of type T;
– BiFunction - like Function but with two parameters;
– BiConsumer - like Consumer but with two parameters;
– BinaryOperator<T> - take two T's as input, return one T as output,
useful for "reduce" operations.
• It also comes with several corresponding interfaces for primitive types,
such as:
– IntConsumer
– IntFunction<R>
– IntPredicate
– IntSupplier
Stream API
• New Java 8 Stream API provides utilities to
support functional-style operations on
streams of values.
• A stream is something like an iterator. The
values “flow past” (analogy to a stream of
water) and then they're gone. A stream can
only be traversed once, then it's used up.
Streams may also be infinite.
Stream API
• There are two types of Streams:
– Sequential: The actions of a sequential stream occur
in serial fashion on one thread.
– Parallel: The actions of a parallel stream may be
happening all at once on multiple threads.
• Usually, dealing with a stream will involve these
steps:
1. Obtain a stream from some source;
2. Perform one or more intermediate operations;
3. Perform one terminal operation.
Stream API
• Threre are two operation types of Streams:
– Intermediate: An intermediate operation keeps the
stream open and allows further operations to follow.
– Lazy operations (e.g. filter, map, flatMap, peek,
distinct, sorted, limit e substream)
– Terminal: A terminal operation must be the final
operation invoked on a stream. Once a terminal
operation is invoked, the stream is "consumed" and
is no longer usable. (e.g. forEach, toArray, reduce,
collect, min, max, count, anyMatch, allMatch,
noneMatch, findFirst e findAny)
Stream API
• There are a couple more general properties of stream
operations to consider:
– Stateful: imposes some new property on the stream,
such as uniqueness of elements, or a maximum number of
elements, or ensuring that the elements are consumed in
sorted fashion. These are typically more expensive than
stateless intermediate operations.
– Short-circuiting : allows processing of a stream to stop
early without examining all the elements. This is an
especially desirable property when dealing with infinite
streams; if none of the operations being invoked on a
stream are short-circuiting, then the code may never
terminate.
Repeating and Type Annotations
• Java 8 will allow annotations to be repeated.
// the first of the month and every monday at 7am
@Schedule(dayOfMont = "first")
@Schedule(dayOfWeek = "Monday", hour = 7)
public void doGoblinInvasion() { ... }
• To do this there is a new method called
obj.getAnnotationsByType(Class annotationClass)
on Class, Constructor, Method, etc. It returns an
array of all such annotations (or an empty array if
there are none).
Repeating and Type Annotations
• In Java 8, annotations can also be applied to the use of types.
This new ability is primarily aimed at supporting type-checking
frameworks, such as Checker. These frameworks help find errors
in your code at compile time.
// Class instance creation:
new @Interned RocketShip();
// Type cast:
notNullString = (@NonNull String) str;
// implements clause:
class ImmutableSet<T> implements
@Readonly Set<@Readonly T> { ... }
// Thrown exception declaration:
void launchRocket() throws @Critical FireException { ... }
New Java Date/Time API
• Java 8 introduces a new Date/Time API that
is safer, easier to read, and more
comprehensive than the previous API.
• Java’s Calendar implementation has not
changed much since it was first introduced
and Joda-Time is widely regarded as a better
replacement.
New Java Date/Time API
• Example:
// Old way
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) + 2);
// New Way
LocalTime now = LocalTime.now();
LocalTime later = now.plus(2, ChronoUnit.HOURS);
New Java Date/Time API
• For timezone specific times you use ZonedDateTime.
// Leaving from San Francisco on July 20, 2013, at 7:30 p.m.
LocalDateTime leaving = LocalDateTime.of(2013, Month.JULY, 20, 19, 30);
ZoneId leavingZone = ZoneId.of("America/Los_Angeles");
ZonedDateTime departure = ZonedDateTime.of(leaving, leavingZone);
// Flight is 10 hours and 50 minutes, or 650 minutes
ZoneId arrivingZone = ZoneId.of("Asia/Tokyo");
departure.withZoneSameInstant(arrivingZone).plusMinutes(650);
// Checks if the specified instant is in daylight savings.
if (arrivingZone.getRules().isDaylightSavings(arrival.toInstant()))
// LEAVING: Jul 20 2013 07:30 PM (America/Los_Angeles)
// ARRIVING: Jul 21 2013 10:20 PM (Asia/Tokyo)
(Asia/Tokyo standard time will be in effect.)
New Java Date/Time API
• Enums
– Java 8 adds several enums, such as LocalDateTimeField and
LocalPeriodUnit, for expressing things like “days” and “hours”
instead of the integer constants used in the Calendar API.
• Clock
– The Clock can be used in conjunction with dates and times to help
build your tests. During production a normal Clock can be used, and
a different one during tests.
//To get the default clock, use the following:
Clock clock = Clock.systemDefaultZone();
//The Clock can then be passed into factory methods;
LocalTime time = LocalTime.now(clock);
New Java Date/Time API
• Working with time zones
ZoneId zone = ZoneId.systemDefault();
Clock clock = Clock.system(zone); // America/Sao_Paulo
ZoneId zone = ZoneId.of("Europe/Berlin");
Clock clock = Clock.system(zone); // Europe/Berlin
Set<String> availableZoneIds =
ZoneId.getAvailableZoneIds();
// [Asia/Aden, America/Cuiaba, Etc/GMT+9, Etc/GMT+8,...
New Java Date/Time API
• Doing calculations with times and dates
Period days = Period.ofDays(5);
LocalTime time = LocalTime.now(); // 15:15:45.562
time.plus(5, ChronoUnit.DAYS);
// throws UnsupportedTemporalTypeException:
Unsupported unit: Days
time.plus(5, ChronoUnit.HOURS); // 20:15:45.562
New Java Date/Time API
• Period parse exploring:
Period parse = Period.parse("P5D"); // Period.ofDays(5)
– For example, the following are valid inputs:
"P2Y" // Period.ofYears(2)
"P3M" // Period.ofMonths(3)
"P4W" // Period.ofWeeks(4)
"P1Y2M3D" // Period.of(1, 2, 3)
"P1Y2M3W4D" // Period.of(1, 2, 25)
"P-1Y2M" // Period.of(-1, 2, 0)
"-P1Y2M" // Period.of(-1, -2, 0)
New Java Date/Time API
• Fluent Date and Time API:
// calculate the payday
LocalDate today = LocalDate.now();
today.with(TemporalAdjusters.lastDayOfMonth()).minusDays(2);
// immutable
LocalDate dateOfBirth = LocalDate.of(2012, Month.MAY, 14);
LocalDate firstBirthday = dateOfBirth.plusYears(1);
New Java Date/Time API
• Different display name types:
DayOfWeek dow = DayOfWeek.MONDAY;
Locale locale = Locale.getDefault();
dow.getDisplayName(TextStyle.FULL, locale); // Monday
dow.getDisplayName(TextStyle.NARROW, locale); // M
dow.getDisplayName(TextStyle.SHORT, locale); // Mon
//It is a valid year?
MonthDay date = MonthDay.of(Month.FEBRUARY, 29); boolean
boolean validLeapYear = date.isValidYear(2010);
// Is leap year?
boolean validLeapYear = Year.of(2012).isLeap();
New Java Date/Time API
• Interoperability with Legacy Code
– Calendar.toInstant() converts the Calendar object to an
Instant.
– GregorianCalendar.toZonedDateTime() converts a
GregorianCalendar instance to a ZonedDateTime.
– GregorianCalendar.from(ZonedDateTime) creates a
GregorianCalendar object using the default locale from a
ZonedDateTime instance.
– Date.from(Instant) creates a Date object from an Instant.
– Date.toInstant() converts a Date object to an Instant.
– TimeZone.toZoneId() converts a TimeZone object to a
ZoneId.
Java API additions
• API additions
– Collections
– Concurrency
– IO/NIO
– Reflection and annotation changes
– Other miscellaneous additions to java.lang, java.util, and
elsewhere
http://www.techempower.com/blog/2013/03/26/everything-about-java-8/
• JDBC 4.2 (Rowset 1.2, REF_CURSOR support, etc.)
http://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/jdbc_42.html
Optional
• Java 8 comes with the Optional class in
the java.util package for avoiding null return
values (and thusNullPointerException).
• Tony Hoare, the invention of the null reference
in 1965 for the ALGOL W programming
language. He calls The Billion Dollar Mistake.
• Used in the Stream API or custom
implementation
Optional
• Examples:
//Creating an instance of Optional using the factory method.
Optional<String> name = Optional.of("Puppy");
name.orElse("Bob")
//This fails with a NullPointerException.
Optional<String> someNull = Optional.of(null);
//This fails with a NoSuchElementException
Optional<String> someNull = Optional.ofNullable(null);
someNull.get();
Nashorn JS Engine
• Nashorn replaces Rhino as the default JavaScript
engine for the Oracle JVM.
• Nashorn is much faster since it uses
the invokedynamic feature of the JVM. It also
includes a command line tool (jjs).
• Java Platform, Standard Edition Nashorn User's Guide
http://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/
• Command line Nashorn:
jjs script.js
Nashorn JS Engine
• Examples:
var data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var filtered = data.filter(function(i) {
return i % 2 == 0;
});
print(filtered);
var sumOfFiltered = filtered.reduce(function(acc, next) {
return acc + next;
}, 0);
print(sumOfFiltered);
Nashorn JS Engine
• Examples:
var imports = new JavaImporter(java.util, java.io, java.nio.file);
with (imports) {
var paths = new LinkedList();
print(paths instanceof LinkedList); //true
paths.add(Paths.get("/"));
paths.add(Paths.get("/home"));
paths.add(Paths.get("/tmp"));
print(paths); // [/, /home, /tmp]
}
Nashorn JS Engine
• Call from Java Class:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");
Reader reader = new FileReader("/home/fmamud/script.js");
engine.eval(reader); // prints: 2,4,6,8,10
30
Other stuffs
• jdeps
– In JDK 8, a new command-line tool, jdeps, is added
that developers can use to understand the static
dependencies of their applications and libraries.
– Java Platform, Standard Edition Tools Reference
http://docs.oracle.com/javase/8/docs/technotes/tools/unix/jdeps.html
– Usage: jdeps <options> <classes...>
where <classes> can be a pathname to a .class
file, a directory, a JAR file, or a fully-qualified
class name.
Other stuffs
• No More Permanent Generation
– Most allocations for the class metadata are now allocated
out of native memory. This means that you won’t have to
set the “XX:PermSize” options anymore (they don’t
exist).
– This also means that you will get a
“java.lang.OutOfMemoryError: Metadata space” error
message instead of “java.lang.OutOfMemoryError:
Permgen space” when you run out of memory.
– This is part of the convergence of the Oracle JRockit and
HotSpot JVMs.
Other stuffs
• Compact profiles
– Java 8 will define subset profiles of
the Java SE platform specification
that developers can use to deploy.
Compact1 have less than 14MB;
Compact2 is about 18MB;
Compact3 is about 21MB.
For reference, the latest Java 7u21 SE Embedded
ARMv5/Linux environment requires 45MB.
• An Introduction to Java 8 Compact Profiles
– https://blogs.oracle.com/jtc/entry/a_first_look_at_compact
Useful links
• What's New in JDK 8
http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html
• JDK 8 Adoption Guide
http://www.oracle.com/technetwork/java/javase/jdk8-adoption-guide-
2157601.html
• Compatibility Guide for JDK 8
http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-
2156366.html
References
• Everything about Java 8
http://www.techempower.com/blog/2013/03/26/everything-about-java-8/
• Java 8 Lambda Expressions Tutorial With
Examples
http://viralpatel.net/blogs/lambda-expressions-java-tutorial/
• Java SE 8: Lambda Quick Start
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/Lambda-
QuickStart/index.html