JDK8
The New Features
Language
Lambdas and functional
interfaces
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello from thread");
}
}).run();
new Thread(() -> System.out.println("Hello from thread")).run()
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Lambdas and functional
interfaces
Arrays.asList("a", "b", "d").sort((e1, e2) -> e1.compareTo(e2));
Arrays.asList("a", "b", "d").sort(
(String e1, String e2) -> e1.compareTo(e2));
Arrays.asList("a", "b", "d").sort(
(e1, e2) -> {
int result = e1.compareTo(e2);
return result;
});
Default methods
interface DefaultInterface {
void show();
default void display() {
System.out.println("Displaying something");
}
}
But … why ??
Default methods
package java.lang;
public interface Iterable<T> {
void forEach(Consumer<? super T> action);
}
Core interfaces have new methods
This breaks backwards compatibility
package java.lang;
public interface Iterable<T> {
default void forEach(Consumer<? super T> action) {
for (T t : this) { action.accept(t); }
}
}
This doesn’t
Static interface methods
interface MyInterface {
void method1();
static void method2() { System.out.println("Hello from static");
}
}
...
MyInterface.method2();
Keep interface related helper methods in the same class rather
than creating a new one
Method references
Static reference
class Example {
public static void main(String[] args) {
String[] str = {"one", "two", "3", "four"};
Arrays.sort(str, Example::compareByLength);
Arrays.sort(str, (s1, s2) -> s1.length() - s2.length());
}
public static int compareByLength(String s1, String s2) {
return s1.length() - s2.length();
}
}
Method references
Instance reference
@FunctionalInterface // New JDK8 interface
public interface Supplier {
T get();
}
public String function(Supplier<String> supplier) {
return supplier.get();
}
public void example() {
final String x = "A string";
function(() -> x.toString());
function(x::toString);
}
Method references
Constructor reference
class Car {}
class Example {
public static Car createCar(Supplier supplier) {
return supplier.get();
}
public static void repair(Car car) {}
public static void main(String[] args) {
Car car = createCar(Car::new);
List cars = Arrays.asList(car);
cars.forEach(Example::repair);
}
}
Repeating annotations
class RepeatingAnnotations {
public @interface Filters { // A hidden filter holder
Filter[] value();
}
@Repeatable(Filters.class)
public @interface Filter {
String value();
}
@Filter("filter1")
@Filter("filter2")
public void filterredMethod() {}
}
Repeat yourself
Extended annotations
class Annotations {
public @interface NotEmpty {}
public static class Holder<@NonEmpty T> extends @NonEmpty Object{
public void method() throws @NonEmpty Exception {}
}
public static void main(String[] args) {
final Holder<String> holder = new @NonEmpty Holder<String>();
@NonEmpty Collection<@NonEmpty String> strings =
new ArrayList<>();
}
}
Annotate anything
Libraries
Optional
Optional<String> name = Optional.ofNullable(null);
System.out.println("Name is set? " + name.isPresent() );
System.out.println("Name: " + name.orElseGet( () -> "[none]" ));
System.out.println(name.map( s -> "Hey " + s + "!" )
.orElse("Hey Stranger!"));
java.util.Optional
Name is set? false
Name: [none]
Hey Stranger!
Streams
for (Student student : students) {
if (student.getName().startsWith("A")){
names.add(student.getName());
}
}
java.util.stream
List<string> names =
students.stream()
.map(Student::getName)
.filter(name -> name.startsWith("A"))
.collect(Collectors.toList());
The old way
The Java8 way
Streams
java.util.stream
int sum =
students.parallelStream()
.map(Student::getName)
.filter(name -> name.startsWith("A"))
.mapToInt(String::length)
.sum();
System.out.println(
Arrays.asList("One", "Two", "Three")
.stream().collect(Collectors.groupingBy(String::length))
);
{3=[One, Two], 5=[Three]}
Date/Time API
JSR 310 - java.time
Date/Time API
JSR 310 - java.time
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) + 2);
LocalTime now = LocalTime.now();
LocalTime later = now.plus(2, HOURS);
The old way
The Java8 way
Nashorn
JavaScript engine
• Rhino replacement
• Faster (2 to 10x performance boost)
• Full ECMAScript 5.1 support + extensions
• Compiles JS to Java bytecode
Nashorn
Example
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
System.out.println(engine.getClass().getName() );
System.out.println("Result:" + engine.eval(
"function f() { return 1; }; f() + 1;" ) );
jdk.nashorn.api.scripting.NashornScriptEngine
Result: 2
Nashorn
Performance
V8 Chrome 31
Spidermonkey F
F 25.0.1
Nashorn
Octane 2.0 14 474 10 066 9 307
Sunspider 1.0.2 220.8 ms 246.5 ms 256.2 ms
http://wnameless.wordpress.com/2013/12/10/javascript-engine-benchmarks-nashorn-vs-v8-vs-spidermonkey/
Base64
Finally … java.util.Base64
final String encoded = Base64
.getEncoder()
.encodeToString( text.getBytes( StandardCharsets.UTF_8 ));
final String decoded = new String(
Base64.getDecoder().decode(encoded),
StandardCharsets.UTF_8);
Tools
jjs
function f() {
return 1;
};
print(f() + 1);
jjs file.js
2
file.js
command
output
Nashorn runner
jdepts
Dependency analyzer
jdeps jdom2-2.0.5.jar
jdom2-2.0.5.jar ->
/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/
rt.jar
org.jdom2 (jdom2-2.0.5.jar)
-> java.io
-> java.lang
-> java.net
-> java.util
-> java.util.concurrent
org.jdom2.adapters (jdom2-2.0.5.jar)
-> java.lang
-> java.lang.reflect
-> javax.xml.parsers
…
command
output
JVM
Metaspace
Thank you :)

JDK 8

  • 1.
  • 2.
  • 3.
    Lambdas and functional interfaces newThread(new Runnable() { @Override public void run() { System.out.println("Hello from thread"); } }).run(); new Thread(() -> System.out.println("Hello from thread")).run() @FunctionalInterface public interface Runnable { public abstract void run(); }
  • 4.
    Lambdas and functional interfaces Arrays.asList("a","b", "d").sort((e1, e2) -> e1.compareTo(e2)); Arrays.asList("a", "b", "d").sort( (String e1, String e2) -> e1.compareTo(e2)); Arrays.asList("a", "b", "d").sort( (e1, e2) -> { int result = e1.compareTo(e2); return result; });
  • 5.
    Default methods interface DefaultInterface{ void show(); default void display() { System.out.println("Displaying something"); } } But … why ??
  • 6.
    Default methods package java.lang; publicinterface Iterable<T> { void forEach(Consumer<? super T> action); } Core interfaces have new methods This breaks backwards compatibility package java.lang; public interface Iterable<T> { default void forEach(Consumer<? super T> action) { for (T t : this) { action.accept(t); } } } This doesn’t
  • 7.
    Static interface methods interfaceMyInterface { void method1(); static void method2() { System.out.println("Hello from static"); } } ... MyInterface.method2(); Keep interface related helper methods in the same class rather than creating a new one
  • 8.
    Method references Static reference classExample { public static void main(String[] args) { String[] str = {"one", "two", "3", "four"}; Arrays.sort(str, Example::compareByLength); Arrays.sort(str, (s1, s2) -> s1.length() - s2.length()); } public static int compareByLength(String s1, String s2) { return s1.length() - s2.length(); } }
  • 9.
    Method references Instance reference @FunctionalInterface// New JDK8 interface public interface Supplier { T get(); } public String function(Supplier<String> supplier) { return supplier.get(); } public void example() { final String x = "A string"; function(() -> x.toString()); function(x::toString); }
  • 10.
    Method references Constructor reference classCar {} class Example { public static Car createCar(Supplier supplier) { return supplier.get(); } public static void repair(Car car) {} public static void main(String[] args) { Car car = createCar(Car::new); List cars = Arrays.asList(car); cars.forEach(Example::repair); } }
  • 11.
    Repeating annotations class RepeatingAnnotations{ public @interface Filters { // A hidden filter holder Filter[] value(); } @Repeatable(Filters.class) public @interface Filter { String value(); } @Filter("filter1") @Filter("filter2") public void filterredMethod() {} } Repeat yourself
  • 12.
    Extended annotations class Annotations{ public @interface NotEmpty {} public static class Holder<@NonEmpty T> extends @NonEmpty Object{ public void method() throws @NonEmpty Exception {} } public static void main(String[] args) { final Holder<String> holder = new @NonEmpty Holder<String>(); @NonEmpty Collection<@NonEmpty String> strings = new ArrayList<>(); } } Annotate anything
  • 13.
  • 14.
    Optional Optional<String> name =Optional.ofNullable(null); System.out.println("Name is set? " + name.isPresent() ); System.out.println("Name: " + name.orElseGet( () -> "[none]" )); System.out.println(name.map( s -> "Hey " + s + "!" ) .orElse("Hey Stranger!")); java.util.Optional Name is set? false Name: [none] Hey Stranger!
  • 15.
    Streams for (Student student: students) { if (student.getName().startsWith("A")){ names.add(student.getName()); } } java.util.stream List<string> names = students.stream() .map(Student::getName) .filter(name -> name.startsWith("A")) .collect(Collectors.toList()); The old way The Java8 way
  • 16.
    Streams java.util.stream int sum = students.parallelStream() .map(Student::getName) .filter(name-> name.startsWith("A")) .mapToInt(String::length) .sum(); System.out.println( Arrays.asList("One", "Two", "Three") .stream().collect(Collectors.groupingBy(String::length)) ); {3=[One, Two], 5=[Three]}
  • 17.
  • 18.
    Date/Time API JSR 310- java.time Calendar cal = Calendar.getInstance(); cal.set(Calendar.HOUR, cal.get(Calendar.HOUR) + 2); LocalTime now = LocalTime.now(); LocalTime later = now.plus(2, HOURS); The old way The Java8 way
  • 19.
    Nashorn JavaScript engine • Rhinoreplacement • Faster (2 to 10x performance boost) • Full ECMAScript 5.1 support + extensions • Compiles JS to Java bytecode
  • 20.
    Nashorn Example ScriptEngineManager manager =new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); System.out.println(engine.getClass().getName() ); System.out.println("Result:" + engine.eval( "function f() { return 1; }; f() + 1;" ) ); jdk.nashorn.api.scripting.NashornScriptEngine Result: 2
  • 21.
    Nashorn Performance V8 Chrome 31 SpidermonkeyF F 25.0.1 Nashorn Octane 2.0 14 474 10 066 9 307 Sunspider 1.0.2 220.8 ms 246.5 ms 256.2 ms http://wnameless.wordpress.com/2013/12/10/javascript-engine-benchmarks-nashorn-vs-v8-vs-spidermonkey/
  • 22.
    Base64 Finally … java.util.Base64 finalString encoded = Base64 .getEncoder() .encodeToString( text.getBytes( StandardCharsets.UTF_8 )); final String decoded = new String( Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
  • 23.
  • 24.
    jjs function f() { return1; }; print(f() + 1); jjs file.js 2 file.js command output Nashorn runner
  • 25.
    jdepts Dependency analyzer jdeps jdom2-2.0.5.jar jdom2-2.0.5.jar-> /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ rt.jar org.jdom2 (jdom2-2.0.5.jar) -> java.io -> java.lang -> java.net -> java.util -> java.util.concurrent org.jdom2.adapters (jdom2-2.0.5.jar) -> java.lang -> java.lang.reflect -> javax.xml.parsers … command output
  • 26.
  • 27.

Editor's Notes

  • #4 Functional interface can have only one abstract method Annotation is optional
  • #16 Real-world functional-style programming into the Java
  • #17 Parallel stream Arrays, BufferedReader
  • #18 New API, Safety (enums), Readability