Java 8 Interesting parts Vaidas Pilkauskas, Kasparas Rudokas Vilnius JUG
May 10, 2015
Java 8Interesting parts
Vaidas Pilkauskas, Kasparas RudokasVilnius JUG
Agenda● Lambda● Date & Time● PermGen● Annotations
LambdaJSR 335
lambda vs. closureA lambda is just an anonymous function.
myCollection.filter(e ‑> e.length() >= 5)
A closure is any function which closes over the environment in which it was defined. This means that it can access variables not in its parameter list.
int minLength = 5;myCollection.filter(new Predicate(){ boolean apply(MyElement e) { return e != null ? e.length >= minLength : false; }})
Project Lambda (JSR 335)● Language changes
○ Lambda Expression○ Virtual Extension Method
● Library changes○ Functional API○ Parallel collections○ Bulk Operations
ProblemString[] names = {"Alice", "Bob", "Charlie", Dave"};Arrays.sort(names, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareToIgnoreCase(o2); }});
"tiny" anonymous inner class String[] names = {"Alice", "Bob", "Charlie", Dave"};Arrays.sort(names, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareToIgnoreCase(o2); }});
"tiny" and useful● callbacks● runnables● event handlers● comparators● ...and many other cases
All we need!String[] names = {"Alice", "Bob", "Charlie", Dave"};Arrays.sort(names, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.compareToIgnoreCase(o2); }});
Solution - closureString[] names = {"Alice", "Bob", "Charlie", Dave"};Arrays.sort(names, (o1, o2) -> o1.compareToIgnoreCase(o2));
What do we mean by closures?
● a unit of deferred execution● code that can be passed as a value● can be used in an assignment
statement● capture of a surrounding environment
Lambda Expressionss -> s.length()(int x, int y) -> x+y() -> 42
(x, y, z) -> { if (x == y) return x; else { int result = y; for (int i = 1; i < z; i++) result *= i; return result; }}
Lambda Syntaxprincipally because something similar has been generally well-received in other Java-like languages (C# and Scala), and a clearly "better" alternative did not present itself
Lambda● Effectively final variables
Lambda● Effectively final variables● Shadowing
Lambda● Effectively final variables● Shadowing● break, continue must be local
Lambda● Effectively final variables● Shadowing● break, continue must be local● this - lambda is not an instance
method. (this == surrounding context object)
Lambda● Effectively final variables● Shadowing● break, continue must be local● this - lambda is not an instance
method. (this == surrounding context object)
● throw completes method abruptly
Functional InterfacesA functional interface is an interface that has just one abstract method, and thus represents a single function contract.
Functional InterfacesSAM - Single Abstract Method interfacesone method excluding Object methodsinterface Runnable { void run(); } // Functional
interface Foo { boolean equals(Object obj); } // Not functional; equals is already an implicit member
interface Comparator<T> { boolean equals(Object obj); int compare(T o1, T o2);}// Functional; Comparator has one abstract non-Object method
Method ReferencesMethod reference is a shorthand for a lambda invoking just that method
System::getProperty"abc"::lengthString::lengthsuper::toStringArrayList::new
Arrays.sort(ints, Integer::compareTo);
Method ReferencesStatic methods simply translate like lambda with same arguments and return type
class Math { public static int max(int a, int b) {...}}interface Operator<T> { T eval(T left, T right);}Operator<Integer> lambda = (a, b) -> Math.max(a, b);Operator<Integer> methodRef = Math::max;
Method ReferencesNon static method reference of type T translates like lambda with an additional argument of type T
Comparator<String> c = (s1, s2) -> s1.compareToIgnoreCase(s2);
//translates to:Comparator<String> c = String::compareToIgnoreCase;
Method ReferencesInstance method reference translates like lambda with same arguments and return type (and implicit receiver)
Callable<Integer> l = () -> "boo".length();//translates to:Callable<Integer> c = "boo"::length;
Method ReferencesString[] names = {"Alice", "Bob", "Charlie", Dave"};Arrays.sort(names, (o1, o2) -> o1.compareToIgnoreCase(o2));
//translates to
String[] names = {"Alice", "Bob", "Charlie", Dave"};Arrays.sort(names, String::compareToIgnoreCase);
Compatibility
Cannot add new interface methods (without forcing current interface users to implement them)
But we need new lambda enabled methods (on Java core libraries!)
Default methods (also known as)
● virtual extension methods● defender methods
Default methodsinterface NormalInterface { void myNormalMethod(); void myDefaultMethod () default { System.out.println("-> myDefaultMethod"); }}
class NormalInterfaceImpl implements NormalInterface { @Override public void myNormalMethod() { System.out.println("-> myNormalMethod"); }}
Functional CollectionsMajor changes in collection API:● Internal iteration support with Iterable/Stream interfaces
(forEach, filter, map, etc)
Functional CollectionsMajor changes in collection API:● Internal iteration support with Iterable/Stream interfaces
(forEach, filter, map, etc)● Explicit parallel APIs for greater parallelism support.
These can be combined with Fork/Join to divide the tasks
Functional CollectionsMajor changes in collection API:● Internal iteration support with Iterable/Stream interfaces
(forEach, filter, map, etc)● Explicit parallel APIs for greater parallelism support.
These can be combined with Fork/Join to divide the tasks
● Greater stress on immutability and avoiding in-place mutation which was done in the conventional for-each loops
ExampleString[] names = {"Alice", "Bob", "Charlie", "Dave"};
List<String> filteredNames = Streams.stream(names) .filter(e -> e.length() >= 4) .into(new ArrayList<>());
filteredNames.stream().forEach(System.out::println);
Streams● No storage - nothing is stored in stream
Streams● No storage - nothing is stored in stream● Functional in nature - new values are produced
Streams● No storage - nothing is stored in stream● Functional in nature - new values are produced● Laziness-seeking. Many operations can be
implemented lazily
Streams● No storage - nothing is stored in stream● Functional in nature - new values are produced● Laziness-seeking. Many operations can be
implemented lazily● Bounds optional. Think of infinite stream
Functional interfacesjava.util.functions● Predicate - a property of the object passed as
argument● Block - an action to be performed with the object
passed as argument● Mapper - transform a T to a U● ...
Parallelism//sequentialint sum = myCollection.stream() .filter(b -> b.getColor() == BLUE) .map(b -> b.getWeight()) .sum();//parallelint sum = myCollection.parallel() .filter(b -> b.getColor() == BLUE) .map(b -> b.getWeight()) .sum();
Advantages● Elements may be computed lazily. If we apply a Mapper
to a collection of a thousand elements but only iterate over the first three, the remaining elements will never be mapped.
Advantages● Elements may be computed lazily. If we apply a Mapper
to a collection of a thousand elements but only iterate over the first three, the remaining elements will never be mapped.
● Method chaining is encouraged. Hence there's no need to store intermediate results in their own collections.
Advantages● Elements may be computed lazily. If we apply a Mapper
to a collection of a thousand elements but only iterate over the first three, the remaining elements will never be mapped.
● Method chaining is encouraged. Hence there's no need to store intermediate results in their own collections.
● Internal iteration hides implementation decisions. For example, we could parallelize a map() operation just by writing myCollection.parallel().map(e ‑> e.length()).
Try it out today!The prototype compiler is being implemented in OpenJDK.● Source code is available at http://hg.openjdk.java.
net/lambda/lambda● Binary snapshots of the lambda-enabled JDK prototype
are available athttp://jdk8.java.net/lambdaIDE support:● Netbeans 8 Nightly Builds with experimental Lambda
support● IDEA 12 EAP with experimental Lambda support
Date & Time APIJSR 310
Oldies: Date● Mutable
Oldies: Date● Mutable● Years being indexed from 1900
Oldies: Date● Mutable● Years being indexed from 1900● Months being indexed from 0
Oldies: Date● Mutable● Years being indexed from 1900● Months being indexed from 0
Ex.: Date d = new Date(1L); System.out.println(d.toString());
Oldies: Date● Mutable● Years being indexed from 1900● Months being indexed from 0
Ex.: Date d = new Date(1L); System.out.println(d.toString()); //Thu Jan 01 02:00:00 EET 1970
Oldies: Calendar● Mutable
Oldies: Calendar● Mutable● Not very convenient (lack of simple field
methods)
Oldies: Calendar● Mutable● Not very convenient (lack of simple field
methods)● Very difficult to extend (add new calendars)
Oldies: Calendar● Mutable● Not very convenient (lack of simple field
methods)● Very difficult to extend (add new calendars)
Ex.: Calendar c = Calendar.getInstance(); int weekday = c.get(DAY_OF_WEEK);
Oldies: Calendar● Mutable● Not very convenient (lack of simple field
methods)● Very difficult to extend (add new calendars)
Ex.: Calendar c = Calendar.getInstance(); int weekday = c.get(DAY_OF_WEEK); Date d = c.getTime();
Under pressure...
JSR 310● Immutable
JSR 310● Immutable● Defines consistent language for domain
○ Offset from UTC vs TimeZone○ Machine vs Human○ ISO 8601
JSR 310● Immutable● Defines consistent language for domain
○ Offset from UTC vs TimeZone○ Machine vs Human○ ISO 8601
● No old Date/Calendar usage (clean)
● Immutable● Defines consistent language for domain
○ Offset from UTC vs TimeZone○ Machine vs Human○ ISO 8601
● No old Date/Calendar usage (clean)● Extensible
JSR 310
JSR 310● Immutable● Defines consistent language for domain
○ Offset from UTC vs TimeZone○ Machine vs Human○ ISO 8601
● No old Date/Calendar usage (clean)● Extensible● Led by JodaTime creator (S. Colebourne)
Example: JSR 310Clock clock = Clock.systemUTC();LocalDate localDate = LocalDate.now(clock);//2012-11-13
Example: JSR 310Clock clock = Clock.systemUTC();LocalDate localDate = LocalDate.now(clock);//2012-11-13
MonthDay brasilBday = MonthDay.of(JUNE, 21);
Example: JSR 310Clock clock = Clock.systemUTC();LocalDate localDate = LocalDate.now(clock);//2012-11-13
MonthDay brasilBday = MonthDay.of(JUNE, 21);
ZoneId zoneId = ZoneId.of("America/New_York");Clock clock = Clock.system(zoneId);ZonedDateTime zonedDateTimeUS = ZonedDateTime.now(clock);//2012-11-11T04:17:58.693-05:00[America/New_York]
Example: JSR 310import static javax.time.calendrical.LocalPeriodUnit.HOURS;
Period p = Period.of(5, HOURS);LocalTime time = LocalTime.now();LocalTime newTime;newTime = time.plus(5, HOURS);// ornewTime = time.plusHours(5);// ornewTime = time.plus(p);
Why not Joda Time?● Machine timelines ● Pluggable chronology ● Nulls● Internal implementation
VM/GCJEP 122 & JEP 156
PermGen removal● Java Heap vs PermGen
PermGen removal● Java Heap vs PermGen
PermGen removal● Java Heap vs PermGen
● Why it was required anyway?
PermGen removal● Java Heap vs PermGen
● Why it was required anyway?● So what?
AnnotationsJSR 308 & JEP 120
Type Annotations● In Java 7 we have annotations on
declarations
Ex.:
class SomeClass { … }class ListElement<E> { … }public void v() (int I) { long l;{
Type Annotations● JSR-308 brings annotations on Type use ● Are an enabler for the checkers framework
Ex.:
new @Interned MyObject(); myString = (@NonNull String) myObject; void monitorTemperature() throws @Critical TemperatureException { ... }
Repeating Annotations● Before
@Schedules ({ @Schedule(dayOfMonth="Last"), @Schedule(dayOfWeek="Fri", hour="23")({public void doPeriodicCleanup() { ... }
Repeating Annotations● Before
@Schedules ({ @Schedule(dayOfMonth="Last"), @Schedule(dayOfWeek="Fri", hour="23")({public void doPeriodicCleanup() { ... }
● After@Schedule(dayOfMonth="Last”)@Schedule(dayOfWeek="Fri", hour="23")public void doPeriodicCleanup() { ... }
Q&A
References* Lambda
http://stackoverflow.com/questions/220658/what-is-the-difference-between-a-closure-and-a-lambda
http://openjdk.java.net/projects/lambda/
http://jcp.org/aboutJava/communityprocess/edr/jsr335/index2.html
http://vimeo.com/48577033 (slides: http://www.slideshare.net/tkowalcz/java-gets-a-closure)
http://datumedge.blogspot.co.uk/2012/06/java-8-lambdas.html
http://www.theserverside.com/news/thread.tss?thread_id=68718
http://medianetwork.oracle.com/video/player/1785479333001
https://oracleus.activeevents.com/connect/sessionDetail.ww?SESSION_ID=6080
https://oracleus.activeevents.com/connect/sessionDetail.ww?SESSION_ID=5089
http://www.lektorium.tv/lecture/?id=14048
http://www.lektorium.tv/lecture/?id=14049
http://blog.xebia.com/2012/11/05/report-will-java-8s-lambda-change-the-face-of-the-world/
http://www.slideshare.net/fsarradin/java-8-lambda
http://programmers.stackexchange.com/questions/173441/what-triggered-the-popularity-of-lambda-functions-in-modern-mainstream-programmi?newsletter=1&nlcode=29983%7c903a
http://www.slideshare.net/bje/java-closures
* Collections
http://www.javabeat.net/2012/05/enhanced-collections-api-in-java-8-supports-lambda-expressions/
http://cr.openjdk.java.net/~briangoetz/lambda/collections-overview.html
http://architects.dzone.com/articles/java-collections-api
References* Remove the Permanent Generation
http://www.cubrid.org/blog/dev-platform/understanding-jvm-internals/
http://javaeesupportpatterns.blogspot.com/2011/10/java-7-features-permgen-removal.html
http://java.dzone.com/articles/busting-permgen-myths
https://oracleus.activeevents.com/connect/sessionDetail.ww?SESSION_ID=5135
* JSR 310: Date and Time API
http://java.dzone.com/articles/introducing-new-date-and-time
http://sourceforge.net/apps/mediawiki/threeten/index.php?title=ThreeTen
http://www.infoq.com/news/2010/03/jsr-310
https://docs.google.com/document/pub?id=1rd8yplQZIRz3LxMzpVLuskr1b0HwBmK9PXpdgBYojSw
http://sourceforge.net/apps/mediawiki/threeten/index.php?title=User_Guide
https://oracleus.activeevents.com/connect/sessionDetail.ww?SESSION_ID=4350
* General Java8
http://openjdk.java.net/projects/jdk8/features
http://www.pcadvisor.co.uk/news/software/3401314/oracle-java-upgrades-still-worthwhile-despite-postponed-features/
http://dhruba.name/2011/07/06/oracle-discusses-java-7-8-new-features-on-video/
http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Java-8
http://www.parleys.com/#st=5&id=2850&sl=1
http://www.parleys.com/#st=5&id=2847
https://oracleus.activeevents.com/connect/sessionDetail.ww?SESSION_ID=2872
https://oracleus.activeevents.com/connect/sessionDetail.ww?SESSION_ID=10458
References*Annotations
https://oracleus.activeevents.com/connect/sessionDetail.ww?SESSION_ID=4469
https://blogs.oracle.com/abuckley/entry/jsr_308_moves_forward
http://jcp.org/en/jsr/detail?id=308
http://openjdk.java.net/jeps/120
http://types.cs.washington.edu/checker-framework/