Search This Blog

Loading...

Sunday, August 14, 2016

Java SE 8 new features tour: Calculating timespans with the new DateTime API

Cleaner, readable, and powerful coding with Java SE 8 New DateTime API JSR 310 .....

Java SE 8, JSR 310
Java SE 8, JSR 310

In this article of the “Java SE 8 new features tour” series, we will deep dig into explanation, and exploring the code of JSR 310 specification, on how to Calculating timespans with the new DateTime API, Calculating time spans with Instant and Duration, Representing date and time values, Formatting date and time values, and Supporting time-zone offsets.

In the previous article “Processing Collections with Streams API”; I have deeply dived into explanation, and exploration on how to traversing collections with streams, Creating streams from collections and arrays, and finally Aggregating stream values.

Source code is hosted on my Github account: clone it from here.

Table of Content:

  1. Calculating time spans with Instant and Duration.
  2. Representing date and time values.
  3. Formatting date and time values.
  4. Supporting time-zone offsets.

1- Calculating time spans with Instant and Duration:

Introduction:

Java SE 8 includes a complete new API for managing date and time values. The classes that actually hold the data in this new API are all immutable and thread safe. So that means you don't have to worry about passing objects around in a multi threading environment. And if you're using them in parallel streams, everything will always work perfectly. All of the classes in this new API are members of the package java.time. And I'll start with two of the core classes named Instant and Duration.

How it works:

I'll start with this example in the package eg.com.tm.java8.features.datetime.InstDuration of project Java8Features. In a class code named InstantAndDuration. And I'll place all this code inside the main method. The first class I'll describe is named Instant. I'll type the name of the class and press Ctrl + Space, and choose the class from the java.time package, and it's imported above. An instant object represents an instant on the Java timeline. Just as with the date class which is a part of the old way of managing dates and times, an instance represents a number of milliseconds.

Since the Java epoch time, January 1st 1970. To declare an instant object, I'll declare it with its type, and give it a name of start. And then I'll call a static method of the instant class called now(). And this represents the moment on the current machine when the code was called. Then I'll output that value as a string, using standard system output. Run the code and you will see the output starting off with the date in year, month, date format and then the time after the letter T.


Result: 2016-08-05T21:21:59.601Z

Once you have a moment in time, you can use it to calculate a difference between that and another moment in time. So I'll create another instant, which I'll call end. And I'll get it's value from the method now() as well. Then I'll use system output, and output that value. Notice that there is a slight difference between the two values, and that's the amount of time it is taking on my system. To process this line of code, that's outputting the start value.


Result:
2016-08-05T21:33:55.971Z
2016-08-05T21:33:56.048Z

If I were to move that line of code down, so I wasn't doing any other processing between the two calls to the now method, the two values would be identical, Or they might be off by a thousandth of a second.


Result:
2016-08-05T21:34:43.365Z
2016-08-05T21:34:43.365Z

Now, I'll show you how to calculate the difference between these two values. When you compare two instants to each other, you'll get an object called a duration. It's represented by the Duration class, which is also a member of Java.time. I'll name this object elapsed. An I'll call a static method of the duration class called between(Temporal startInclusive, Temporal endExclusive). Notice that it's looking for objects typed as something called Temporal. The Instant class is a sub-class of Temporal.


Result: Elapsed: PT0S

I'll pass in start and end as my two temporal values. And then I'll output the difference. I'll pass in a literal label of elapsed, and then I'll pass in my variable. That duration object starts with the letter p and then t for time. This is again an ISO formatted value. And then it shows me zero seconds. Well let's see what happens if we toss in a call to the sleep method. I'll place the cursor here between the start and end calls. And I'll use the Thread class.


I'll press the period, and then press Ctrl+Space. And then I'll call the sleep() method and pass in a value of 1,000. Meaning sleep for one second. The sleep method can throw an error, so I'll use a quick fix, and I'll add a throws declaration to the main methods signature. I'll save and run the code, and I see that my lapse time is now 1.001 seconds. You can never really count on things being exact, it all depends on what's going on, on the processing computer.


Result: Elapsed: PT1.001S

Next, I'll take this printline call, and move it back to its original location. So now after I get the start value, I'll be executing a printline command. And I'll be sleeping for one second. And I'll run the code. And now my lapse time is 1.057 seconds.


Result:
2016-08-05T22:28:42.685Z
2016-08-05T22:28:43.769Z
Elapsed: PT1.084S

To make this a little bit more readable, I'll add a call to the method of the duration object using elapsed.to millis. That means, get the milliseconds equivalent. And I'll append to that, milliseconds, and I'll run the code.


Result:
2016-08-05T22:32:52.657Z
2016-08-05T22:32:53.731Z
Elapsed: 1074 milliseconds


Conclusion:

And now I see, a readable value, of 1,054 milliseconds. So, that's the Instant class and the Duration class. Two of the core classes, of the new date time API, in Java SE 8.

2- Representing date and time values:

Introduction:

I previously described how to use the instant class in the new date time API to represent a moment in the Java timeline. Here are three more useful classes to represent parts of dates and times. They're called local date, local time, and local date time. Lets say, for example, that you only want to represent a date value. And you don't care about times or seconds or milliseconds but only the current date. Create an instance of a class named LocalDate.

How it works:

I'm working in a package eg.com.tm.java8.features.datetime.localdt of project Java8Features. In a class code named LocalDateAndTime. with a main method. I'll start with the name of the class LocalDate. And when I press Ctrl + Space, I'll choose the class from the java.time package. I'll name the object currentDate and I'll get its value with localDate.now. Notice that there's consistency in the syntax between working with an instant, a date, a time and a date time.

To get the current value on the current machine, you always use the now method. Now, I'll output that date in its default format. I'll save and run the code, and it shows me the date in year-month-date format.


Result:
2016-08-06

You can also create a date object using specific year, month, and date values. Once again, I'll create an object typed as LocalDate. And I'll name this one specificDate. To get this value, call LocalDate.of.

And there are a couple of available versions. I'm going to use the one that takes three integer values. They aren't named in the documentation but they represent the year, the month, and the day. I'll patch in the values of 2,000, 1, and 1. Now, in the older version of the date time API using the date class. When you were dealing with months, you always had to do it with a 0 based off set. So for January you'd use 0, for February 1 and so on.

And that wasn't particularly intuitive. In the new day time API, everything is 1 based. So 1 means January, 2 means February and so on. Just as you would normally expect.

I'll once again use system output, and this time I'll, I'll put the new specific date. And when I save and run that, I get the value that I put in, January 1st, 2000.


Result:
2016-01-01

If you only want to represent a time value, use the LocalTime class, I'll type the name of the class and import it, I'll name the object currentTime and I'll get its value from LocalTime.now.

Again, using the same sort of syntax as with localdate and with instant. Then I'll use system output. And I'll output that current time. The default value for the time is in 24 hour notation, and it shows the hour, the minute, the second, and the milliseconds.


Result:
01:18:11.779

I'll use LocalTime. I'll name this specificTime. And, just as with the local date class, I'll call the method named of. Again, there are a number of different versions taking varying numbers of arguments.

I'll use the version that's looking for three integer values and I'll type in 14, 0 and 45. And then I'll output that value to the console. And there's the result. 14, 00 and 45 seconds. Notice that because I didn't provide a milliseconds value the formatted version of that time doesn't show values after the dot.


Result:
14:00:45

Finally, I'll show how to use the LocalDateTime class.

I'll type the name of the class and import it. I'll name this object currentDT. And I'll get its value from LocalDateTime.now. When you output a date time value, you'll get a long format ISO date time. Starting with the date, and ending with the time. And if there are milliseconds in the value, they'll be displayed. And finally, I'll create a specific date, time and I'll do this by combining my specific date and my specific time.

That code will look like the next code. I'll create a LocalDateTime object. I'll name it, specificDT and I'll call LocalDateTime.of again. And this time, I'll use this first version of the method that accepts a local date object and a local time object. You can also construct your date time value from combinations of years, months, dates, and time values. I'll pass in my specific date and my specific time. And then I'll output it to the console. And when I run that code, my specific date time is a combination of my specific date and my specific time.


Result:
2016-08-06T01:30:46.625
2016-01-01T14:00:45

Conclusion:

So, those are the three classes that you can use to represent date and time values on the local machine in the current time zone. There are also classes you can use to get time zone sensitive values. And I'll describe those next.

3- Formatting date and time values:

Introduction:

I've previously described how to use the LocalDate, LocalTime, and LocalDateTime classes to represent time values. To present this information to a user, you'll need to format it. And for that purpose, there's a new class named DateTimeFormatter. I'll show you how to create formatters using some simple syntax. And then how to do very custom work using a class called Daytime Formatter Builder.

How it works:

I'm working in a package eg.com.tm.java8.features.datetime.format of project Java8Features. In a class code named DateTimeFormater. with a main method.

First, I'll create a date. I'll give it a type of LocalDate, making sure to import that class. And I'll name it currentDate. And I'll get its value from LocalDate.now. Next I'll create a formatter object. I'll type the name of the class, DateTimeFormatter, and select it from the java.time.format package. I'll name this object df. Now there are a number of ways of creating a formatter. One of the simplest is to use a constant of the DateTmeFormatter class.

I'll once again type in DateTimeFormatter. And then after I type in the period I see a list of all of the available constants. I'll choose ISO Date. And this will provide the default formatting for this object. Then, I'll use System Output. I'll call the formatted object format method and pass in the date object. And here is the result. I'm outputting the value in year month date format. With the month and the date padded out to two characters each. Now you can do the same sort of thing with times and date times.


Result:
2016-08-06

I'll take above bit of code and I'll duplicate it a couple of times and I'll make some changes. In the second version, I'll change the type from local date to local time. The object name to current time, and the name of the class I'm using to get the value to local time. I'll change the name of the date time formatter from DF to TF for time formatter. And I'll change the constant I'm using to ISO Time. And then I'll change the object that I'm formatting. I'll be sure to import the LocalTime class.

And then I'll make similar changes to the third version. The class that I'll be working with this time is LocalDateTime. I'll be sure to import it. I'll name this object, current DT. And I'll change the class that I'm calling the now method from. I'll change the formatter to DTF for DateTimeFormatter. And I'll change the constant to ISO Date Time. And then I'll format the current DT object. I'll be sure I'm using the right formatters in each version of the code. I'll save the change, and run the code.


And there are the three formatted values. Now so far, I haven't really accomplished that much, because I've used the constants that represent the default formatting. But let's take a look at some custom formats that are available.

Result:
2016-08-09
20:37:11.535
2016-08-09T20:37:11.538

I move down to below the existing code. And i'll create another DateTimeFormatter, i'll name this one f_long for the long date format and i'll get its value by calling a method of the DateTimeFormatter class called a Localised Date.

Notice that there are methods for date, time and date-time, with a variety of arguments. I'll choose this one, of localized date, and I'll pass in a constant of a class called, FormatStyle. Be sure to import this class. And then after you type the period, you'll see that there are four constants available. Full, long, medium and short. I'll choose the long version and then I'll output the formatted date by calling F _ long.format and I'll pass in the current DT object.


When i run this code i get the long version of the date.
Result:
August 9, 2016

I'll show you another version of this by duplicating these two lines of code and for this version i'll change the formatter name to f_short, i'll change the constant I'm using to short also. And I'll change the name of the formatter that I'm calling. So the long version is the name of the months spelled out. A comma after the date, and then the year in four digit format, and the short version at least for the current locale, is the month and date, without padding, with slashes separating values, and a two character year.


Result:
8/9/16

And next, I'll show you how to use locales. I'll create a couple of strings. The first will be called fr_ short, for French, in short format. To get that value i'll call my f_short formatter and then i'll will call method name withLocal(). To get a locale value i'll use the Local class, this is an existing class that's been available in previous versions of Java. It's a member of the package Java.util.

And then, I can call one of the many constants representing various locales. I'll use French. And then from there, I'll call the format method, and pass in the current date time.

I'll duplicate that line of code and for this version I'll use fr_long. I'll use the long formatter and otherwise the code will be the same. And then I will output those two values fr_short and fr_long.


And here's the result. Notice for fr_short that the month and the day are reversed from the US version. And that's because in Europe, the date is stated first, and then the month, and then the year. And when I use the long version I get the months spelled in French.

Result:
09/08/16
9 août 2016

Finally I'll show you how to build completely custom formatters using a class called the date time formatter builder. It uses the builder design pattern, where you can call multiple methods, each returning an instance of the current builder.

I'll type the name of the class and make sure that it's been imported. And I'll name the object b. I'll instantiate it with the new keyword, and the constructor method.

Now, at the end of that code I won't put in the semicolon because I want to immediately call a series of methods that let me build the formatter from scratch. I'll start with a method named Append Value. Notice there's Append Instant, Append Literal, Append Localized and many many others. I'm going to call a method named appendValue() that accepts an instance of a class named TemporalField and then I'll use an enumerator named ChronoField. Which is extended from that TemporalField.

And from there I'll use a constant name month of the year. Next I will append a literal value. This can be any character or any string. And just to make this thoroughly unique, I'll put in a couple of pipe characters. Now I'll take these two lines of code and duplicate them for the second version instead of month of year. I'll put in day of month. Notice there's also day of week and day of year. Then I'll duplicate that line of code and move it down. And I'll finish the expression with ChronoField.year.

Once you've created the builder object, you can get the formatter. I'll create new object, typed as DateTimeFormatter. I'll name it f for Formatter. And called builder objects, to formatter methods, and then finally I'll format the current date time value. I'll use system output and call f.format(), and pass in currentDT.


And now when I run my code, I get completely customized format.
Result:
222||9||2016

Conclusion:

You can use the DateTimeFormatter builder to build any format you like. And because it uses the builder design pattern, it's easy to create and to maintain the code.

4- Supporting time-zone offsets:

Introduction:

The new date time API offers a number of classes that let you manage time zones. Creating day time objects that are offset from Greenwich Mean Time, by certain number of hours, or by particular locations, and calculating differences between time zones.

How it works:

I'm working in a package eg.com.tm.java8.features.datetime.zone of project Java8Features. In a class code named TimeZones. with a main method.

In its main method, I've created a DateTimeFormatter and a LocalDateTime object. The LocalDateTime represents the current date and time on my system, in my time zone. And that's Egyptian Time because I'm on the Middle East.


And then I'm outputting a formatted value to the console. I'm outputting the value using a short format. And in Egypt notation, it's month, day and year.

Result:
8/9/16 10:22 PM

In order to represent a time zone based date time value, use the class ZonedDateTime. Just like LocalDateTime, it's immutable and thread safe. I'll type the name of the class, and then press Control + Space to add the import statement. And I'll name the object gmt for Greenwich Mean Time.

There are a few different ways of creating this object. I'll show you how to create the object calculating an offset from Greenwich Mean Time. I'll use the ZonedDateTime class again, and after I type the period, I'll see that there are many methods available. I can call now() again, to get the date time value in my area. I can call of() methods that let me do various calculations. I can parse strings, but I'm going to use this version of the now method. I'll pass in an instance of the ZoneId class.

A ZoneId represents a certain number of hours offset from Greenwich Mean Time. And I'll get that value by calling a method named ZoneId.of(). And I'll pass in a literal string of "GMT+0". That means, show me the current date and time value in Greenwich Mean Time.


Now I'll duplicate my code that's outputting the value to the console. I'll move that down, and I'll change this version to output gmt. I'll run the code, and there's the result.

Result:
8/9/16 8:28 PM

I'm in the Middle East Egypt, and right now, Greenwich Mean Time is two hours ahead.

Here is another approach to getting a ZonedDateTime. Lets say you wanted to get the ZoneDateTime in New York. There are many built-in strings, or constants, that will let you name particular locations, and you'll get back the correct ZoneId for that location, and you won't have to worry about the math yourself. I'll create another ZonedDateTime object, and this time i'll name it ny for New York, and I'll get it value by calling ZonedDateTime.now(), and again I'll pass in ZoneId.of(), but this time i'll pass in a string of America/New_York.

Make sure to spell this string exactly as you see it here. I'll create a line of code to output that value. I'll save the change, and run it. And New York is on East Coast time, three hours ahead of Pacific time.


Result:
8/9/16 4:36 PM

To find out about all of the available strings, you can call a method of the ZoneId class called getAvailableZoneIds(). You'll get back a set. I'll type Set and press Control + Space, and then choose set from Java.util.

And I'll set the generic type of the items in this set to String. I'm name the set zones. And then I'll call the method, ZoneId.getAvailableZoneIds. Then I'll loop through the strings with the forEach() method. And then I'll pass in a Lambda expression. So I can deal with each of the items in turn.


Result:
When I run that code, I see all of the available strings.
Asia/Aden
America/Cuiaba
Etc/GMT+9
Etc/GMT+8
Africa/Nairobi
America/Marigot
Asia/Aqtau
Pacific/Kwajalein
America/El_Salvador
Asia/Pontianak
Africa/Cairo
Pacific/Pago_Pago
Africa/Mbabane
Asia/Kuching
Pacific/Honolulu
Pacific/Rarotonga
America/Guatemala
Australia/Hobart
Europe/London
America/Belize
America/Panama
Asia/Chungking
America/Managua
America/Indiana/Petersburg
Asia/Yerevan
Europe/Brussels
GMT
Europe/Warsaw
America/Chicago
Asia/Kashgar
Chile/Continental
Pacific/Yap
CET
Etc/GMT-1
Etc/GMT-0
Europe/Jersey
America/Tegucigalpa
Etc/GMT-5
Europe/Istanbul
America/Eirunepe
Etc/GMT-4
America/Miquelon
Etc/GMT-3
Europe/Luxembourg
Etc/GMT-2
Etc/GMT-9
America/Argentina/Catamarca
Etc/GMT-8
Etc/GMT-7
.................

Now, there are so many it might be hard to find the one that you're looking for. So let's say that I wanted to look for London.

And use the time zone for that particular location, at this particular time of year. As I showed earlier in the article, I could use a predicate to search the strings. I'll create a predicate object. And I'll set the generic type to String. And I'll name the object condition. Then I'll implement the predicate with a lambda expression. I'll pass in str, and then I'll implement the predicate with a condition. str.contains, and I'll pass in a string of London.

Then I'll refactor my Lamba expression. I'm going to wrap System.out.println() in braces. Then I'll expand the code to make it a little bit easier to work with. I'll add the semi colon at the end of the print line, and then I'll create an if statement. And I'll set the condition to condition.test(), and I'll pass in z for the current zone. I'll move the println() statement, to within the condition, and now i'll only printout strings that match my predicate test.


I'll save the change and run the code, and there's the result. I find that the correct string for London is:

Result:
Europe/London


Conclusion:

So that's a little bit about working with time zones. Again, use the ZonedDateTime class instead of LocalDateTime to represent values that you can modify and calculate against. The ZoneId represents an off set from Greenwich Mean Time. And there's also a class called Zone Offset that you can use to calculate different time zones against each other.

Resources:
  1. The Java Tutorials, Trail: Date Time
  2. The LocalDate API
  3. JSR 310: Date and Time API
  4. JSR 337: Java SE 8 Release Contents
  5. OpenJDK website
  6. Java Platform, Standard Edition 8, API Specification

I hope you enjoyed reading it, as I enjoyed writing it, please share if you like it, spread the word.



Saturday, July 25, 2015

Java SE 8 new features tour: Processing Collections with Streams API

Cleaner, readable, and powerful coding with Java SE 8 Streams.....

In this article of the “Java SE 8 new features tour” series, we will deep dig into explanation, and exploring the code, on how to traversing collections with streams Creating streams from collections and arrays, Aggregating stream values.

In the previous article “Traversing, filtering, processing collection, & methods enhancements with Lambda”; I have deeply dived into explanation, and exploration on how to traverse the collections using lambda expression and with method references, filtering them with predicate interface, implementing default methods in interfaces, and finally implementing static methods in interfaces.

Source code is hosted on my Github account: clone it from here.

Table of Content:

  1. Traversing collections with streams.
  2. Creating streams from collections and arrays.
  3. Aggregating stream values.

1- Traversing collections with streams:

Introduction:

Java's collections framework lets you easily manage ordered and unordered collections of data in your applications, using interfaces like List and Map, and classes like Arraylist and HashMap. The collections framework has continually evolved since its first introduction. And in Java SE 8, we now have a new way of managing, traversing, and aggregating collections with the stream API. A collection based stream isn't like an input or an output stream.

How it works:

Instead it's a new way with working with data as a whole instead of dealing with each item individually. When you use streams, you don't have to worry about the details of looping or traversing. You create a stream object directly from a collection. And then you can do all sorts of things with it including traversing, filtering, and aggregating its values. I'll start with this example in the package eg.com.tm.java8.features.stream.traversing of project Java8Features. In a class code SequentialStream, in Java SE 8 there are two kinds of collection streams known as sequential and parallel streams.


A sequential stream is the simpler of the two and just like an iterator it will let you deal with each item in a collection one at a time. But with less syntax than before. In this code, I've created an array list of people, cast as a list. And it has three instances of a complex object, a class named Person. Then I'm using a Predicate to declare a condition, and displaying people that only satisfy the condition. From lines 48 to 52 in the displayPeople() method, I'm traversing the collection, looping through the data, and testing each item one at a time. run the code and you should have the following results:


I'll show you how to re-factor this code using a stream object. First, I'm going to comment out these lines of code. Now, below the commented code, I'll start with the collection object. People. And then I'll call a new method called stream. A stream object, just like the collection itself, has a generic declaration. If you get a stream from a collection, the items in the stream are of the same type as the collection itself. My collection has instances of the person class so the stream uses the same generic type.


You call stream as a method, and now you have a stream object that you can do things with. I'll start with a simple call to the four each method, and this will require a Lamda expression. I'll pass in the argument. That's the item in the list that I'm dealing with on this time through the iteration. Then the Lambda operator and then the implementation of the method. And I'll use simple system output and I'll output the person's name. I'll save and run the code and there's the result. Because I'm not filtering anymore, I'm displaying all of the people in the list.


Now, once you have a stream this is how easy it'll be to use a predicate object. When I use the for each method and dealt with each item one at a time. I had to explicitly call the test method of the predicate. But using a stream you can call a method named filter. That expects a predicate object, and all predicates have a test method, and so it already knows how to call that method. So, I'll break up this code a bit. I'll move the call to the .forEach() method down a couple of lines, and then on the empty line in the middle, I'll call the new filter method.


The filter method expects an instance of the predicate interface. And I'll pass my predicate object in. The filter method returns the stream but now the filtered version, and from there I can call the forEach() method. I'll run the code and now I am only displaying items from the collection that satisfy the predicate condition. You can do lot more with the streams. Take a look a the documentation for streams in the Java SE 8 API docs.


And you'll see that in addition to filtering you can also aggregate and do all sorts of other things with streams. Before I conclude this demonstration though, I want to show you a very important distinction between sequential and parallel streams. One of the goals of the stream API in Java SE 8 is to let you break up processing on a system that has multiple CPUs. This multi CPU processing is handled automatically by the Java runtime. All you need to do is turn your sequential stream into a parallel stream.

And there are a couple of ways of doing that syntactically. I'll make a copy of my sequential stream class. I'll go to my package explorer, and I'll copy it and paste it. And I'll name the new class, ParallelStream. And I'll open the new class. In this version, I'll get rid of the commented code. I don't need that anymore. And now here are two ways of creating a parallel stream. One approach is to call a different method from the collection. Instead of stream I'll call parallelStream(). And now I have a stream that will automatically be broken down and allocated to different processors.


I'll run the code and I'll see that it's doing exactly the same thing, filtering and returning the data.


Here is the other way to create a parallel stream. I'll call this stream() method again. And then from the stream method I'll call a method named parallel() and that does exactly the same thing. I start with the sequential stream and I end up with a parallel stream. It's still a stream. It can still filter, it can still process in exactly the same way as before. But now it'll be broken up where possible.


Conclusion:

There isn't any clear prescription for when to use a parallel stream over a sequential stream. It depends on the size and complexity of your data, and the capabilities of the hardware. The multi CPU system that you're running on. The only recommendation I can give you is to try it with your application and your data. Set up benchmarks, timing the operation. Use a sequential stream and use a parallel stream and see which works better for you.

2- Creating streams from collections and arrays:

Introduction:

Java SE 8's stream API is designed to help you manage collections of data, that is objects that are members of the collection's framework, such as array lists or hash map. But you can also create streams directly from arrays.

How it works:

In this project Java8Features, in the package eg.com.tm.java8.features.stream.creating, I have a class named ArrayToStream. And in its main method, I've created an array of three items. And they're each instances of my complex object, the Person class.


This class has setters and getters for the private fields, and the new getInfo() method, to return a concatenated string.


Now if you wanted to use a stream to process this array, you might think you would need to convert it to an array list, perhaps and then from there create the stream. But it turns out there are a couple of ways to go directly from an array to a stream. Here's the first approach. I'm not going to need these three lines of code that I'm using to process the data. So I'll comment those out. And then down here, I'll declare an object for the type is stream.

Stream is an interface, which is a member of java.util.stream. When I press Ctrl+Space and select it from the list, I'm asked for the generic type of the items, that the stream will manage. And these will be items of type Person, just like the items in the array itself. I'll name my new stream object, stream, in all lower case. And here's the first way to create the stream. Use the stream interface again, and call a method named of(). Notice that there are a couple of different versions.

One that takes a single object, and one that takes a series of objects. I'll use the one that takes one argument, and I'll pass in my array, people, and that's all I need to do. Stream.of() means take this array and wrap it inside a stream. And now i can use lambda expressions, filters, method references and other things that work on Stream objects. I'll call the stream objects for each method and i will pass in a lambda expression, i'll pass in the current person and then after the lambda operator, i'll output the person's information. Using the object's getInfo() method.


I'll save and run the code and there's the result. I'm outputting the items in the same order in which they were placed in the array. So, that's one approach using Stream.of().


There's another approach that does exactly the same thing. I'm going to duplicate that line of code, and comment out one version. And this time in using Stream.of(), I'll use a class named Arrays, which is a member of the package java.util.

And from there, I'll call a method named stream. Notice the stream method can be wrapped around arrays of a variety of types. Including both primitives and complex objects.


I'll save and run that version and the stream does exactly the same thing as before.


Conclusion:

So either Stream.of() or Arrays.stream() will do exactly the same thing. Take an array of primitive values or complex objects and turn them into a stream, that you can then use with lambdas, filters, and method references.

3- Aggregating stream values:

Introduction:

I've previously described how to use a stream to iterate over a collection. But you can also use streams to aggregate items in a collection. That is, calculate sums, averages, counts, and so on. When you do this kind of operation, it's important to understand the nature of parallel streams.

How it works:

So I'm going to start this demonstration in the project Java8Features, in the package eg.com.tm.java8.features.stream.aggregating. And I am going to first work with the class ParallelStreams. In this class's main method I've created an array list containing string items.

I'm using a simple for loop I've added 10,000 items to the list. Then on lines 35 and 36, I'm creating a stream and using the for each method and outputting each stream one at a time.


When I run this code, I get an expected result. The items are output to the screen in the same order in which they were added to the list.


Now let's see what happens when we turn this into a parallel stream. As I described previously, I can do this either by calling the parallel stream method or by taking the results of stream and passing those to parallel.

I'll do the latter. Now I'm working with a parallel stream, that is a stream that can be broken up and the work load split among multiple processors.


I'll run the code again and watch what happens, notice that the last item printed is not the last item in the list. That would've been 9,999. And if I scroll around in the output I'll see that the processing is jumping around in someway. What's happening is that the run time is arbitrarily splitting the data into blocks.


And then handing each block to an available processor. It's only after all of the blocks have been processed that my next bit of Java code would be executed. But internally, within the call to the forEach() method, all of this work is being split up as needed. Now this might or might not provide a performance benefit. It depends on the size of your data set. And the nature of your hardware. But one of the things that this example shows you is that if you need to process items sequentially, that is one at a time in the same order in which they were added to the collection, then a parallel stream might not be the way to do it.

Sequential streams can guarantee they're working in the same order every time. But a parallel stream, by definition, is going to do things in the most efficient way possible. So parallel streams are especially useful when you're aggregate operations. Where you're taking into account all of the items in a collection and then creating a some sort of aggregate value from them. I'll show you examples of counting items in a collection, averaging them, and summing them using strings.

In this class, CountItems in the main method, I'm starting with the same basic code. Creating 10,000 strings in a list. And then there's a for each method that's looping through and handling them one at a time.


In this example, instead of processing each string individually, I instead want to count them up. So, I'll comment out that code, and here's the code I'll use. Since I don't know exactly how many items are going to be in the collection. I'll cash the result I am about to create as a long integer.

And I'll name it count, and I'll get it's values by calling strings. That's my collection, .stream(), .count(), and this returns a long value. Then I'll use system output and I'll report the result. With count: and then I'll append my result.


I'll save my changes and run the code and there's the result. The count of the items in the collection is almost instantaneous.


Now to make this a little bit more dramatic I'll add a couple of zeros here and now I'm dealing with 1,000,000,000 strings. I'll run the code again and the result comes back again almost instantly.


Now watch what happens if I instead parallelize the string. I'll add dot parallel here,.


And then I'll run the code, and it takes a little bit longer. Now, I could benchmark how long it's taking these operations to happen, by capturing the current time stamp before and after the operation. And then doing a little math. And what it would show might differ from one system to another. But in my experience when dealing with these sorts of simple collections containing simple values there isn't much benefit to parallel streams. Your mileage may very though. And I encourage you to do your own benchmarking. But that's how you would do a count.

Let's take a look at summing and averaging. I'll go to my class SumAndAverage. This time, I have a list of three person objects, each with a different age. And my goal is to get the sum of the three ages, and the average of the three ages. I'll add a new line of code after all the instances of the person class have been added to the list. And I'll create an integer variable that I'll name sum.

I'll start by getting a stream, using people.stream(). From there I'll call a method called mapToInt(). Notice that there's a Map Method. mapToDouble() and mapToLong() as well. The purpose of these methods is to take complex object and extract a simple primitive value from it, and create stream of those values, and you do this with Lambda expression. So, I'll choose mapToInt() because the ages of each person are integers.

For the Lambda expression, I'll start with a variable that will represent the current person. Then the Lambda operator and then an expression that returns an integer. I'll use p.getAge(). This returns something called an int string or a string of integers. There's also a double string class and a few others. Now from this stream because I already knew it was a numeric value I can call a method named sum(). And that's it. I've now summed up all the aged values from all the personals object in my collection. With a single statement, I'll output the result using System Output. My label will be total of ages and I'll append to that my sum.


I'll save my code and run it. And the total of all three ages is 100.


Averaging these values is very similar. But because whenever you're doing averaging your doing divisions, and you might get a divide by zero problem, and so, when you do an average, you'll get back something called an Optional variable.

And there are a number of types you can use for this. For my averaging, I'm going to expect a double value to come back. So, I'm going to create a variable, called OptionalDouble. Notice that there's also Optional Int and Optional Log. I'll name my variable Avg, for average. And I'll use this same sort of code I just used to get the sum, starting with people.stream(). And then from there, I'll use mapToInt() again. And I'll pass in the same lambda expression that i use last time, and then from there I'll call the average method.

Now with an OptionalDouble object, before you process it you should always make sure that it actually has a double value and you do this with a method named isPresent(). So, I'll start off with an if else code template. And I'll set my condition to avg.isPresent(). If that condition is true, I'll use System Output. And I'll label this just Average. And I'll append my average variable. In the else clause I'll simply say that the average wasn't calculated.


Now in this example I know it will be successful because I've provided ages to all three people but that won't always be the case. Like I said if you end up with a divide by zero situation you might not get a double value back. I'll save and run the code, and notice that with the optional double class, it's a complex object.


So the type is wrapped around the actual value. I'll go to this code, where I'm referencing the object directly, and I'll call it's getAsDouble() method.


And now I'll get back a primitive double value. I'll run the code again and now the result is what I was looking for.


Conclusion:

So using streams and lambda expressions, you can easily calculate aggregate values from collections with a tiny, tiny amount of code.

Resources:
  1. The Java Tutorials, Aggregate Operations
  2. The Java Stream Interface API
  3. The Java Tutorials, Lambda Expressions
  4. JSR 310: Date and Time API
  5. JSR 337: Java SE 8 Release Contents
  6. OpenJDK website
  7. Java Platform, Standard Edition 8, API Specification

I hope you enjoyed reading it, as I enjoyed writing it, please share if you like it, spread the word.



Saturday, July 4, 2015

My JavaFX 8 essentials book is now available on Packt and Amazon

JavaFX essentials Book

I would like to take this opportunity to announce that my book "JavaFX 8 essentials" has been published yesterday on Packt publishing web site and Amazon.com as well.

This is my first post for this year 2015, it really was a very hard task and it took around 8 months of writing with all the other book stages till the publication, especially the changes that has been made during the last couple of months.

From Oracle none support for embedded JVM, the appearance of Gluon plug-in, and stop support for JavaFX scene builder, and 4 JDK updates which requires the changes in chapters more and more so the book is still up-to date to the final releases.

At the same time changes for other vendors like Raspberry Pi, Arduino, Leap Motion, Mobile (Android and iOS) software and hardware.

The book will teach:

  • Deliver complex, compelling, and high performance JavaFX 8 applications with new impressive Java SE 8 core features and enhancements.
  • Run JavaFX applications on embedded devices such as Raspberry Pi.
  • Use Scene Builder to create and define UI screens graphically and save them as JavaFX FXML-formatted files.
  • Develop amazing gesture-based applications and an interactive touch-less JavaFX application with Leap motion devices.
  • Get hands-on knowledge about mobile development and create native JavaFX applications for Apple iOS and Android platforms.
  • Use JavaFX with an Arduino board to develop desktop applications to monitor data coming from the real world or control real devices.


You can get the book from the following links:

http://www.amazon.com/JavaFX-Essentials-Mohamed-Taman/dp/1784398020/ref=sr_1_1?s=books&ie=UTF8&qid=1435742004&sr=1-1&keywords=JavaFX+Essentials

https://www.packtpub.com/web-development/javafx-essentials

Sunday, November 30, 2014

Java SE 8 new features tour: Traversing, filtering, processing collection, & methods enhancements with Lambda

Cleaner, readable, and powerful coding with lambda expressions.....

In this article of the “Java SE 8 new features tour” series, we will deep dig into explanation, and exploring the code, on how to traverse the collections using lambda expression and with method references, filtering them with predicate interface, implementing default methods in interfaces, and finally implementing static methods in interfaces.

In the previous article “Functional programming with Lambda Expression”; I have deeply dived into understanding lambda expressions. I have shown you a few different uses of Lambda Expressions. They all have in common the implementation of functional interfaces. I have also explained how the compiler is inferring information from code, such as specific types of variables and what is really happening in the background.

Source code is hosted on my Github account: Clone it from here.

Table of Content:

  1. Traversing collections with lambda expressions.
  2. Filtering collections with predicate interfaces.
  3. Traversing collections with method references.
  4. Implementing default methods in interfaces.
  5. Implementing static methods in interfaces.

1- Traversing collections with lambda expressions.

In Java SE 8, you can use lambda expressions to traverse a collection of items. Examples of collections include lists, maps, and sets. All of these data types implement an interface called iterable. To understand the code I'm about to show you, let's start in the documentation. I'm working a class called TraverseFileContent.java under eg.com.tm.java8.features.lambda2 package. I'll right click into the method name readAllLines and then Show Javadoc.

It returns List class that extends a number of interfaces. This is the one I'm interested in called iterable. This interface was added in Java SE 5. And it has a method called iterator. That returns an instance of an Iterator interface that you can use then to loop through the contents of a collection. But in Java SE 8 there were a couple of new methods. One called forEach, and one called spliterator. I'm going to focus on the forEach method.

It accepts an instance of a functional interface, called Consumer. The consumer interface has a single abstract method, named accept. And by implementing this interface and its single abstract method, you can add code that operates on an item in the collection.

So, let's go back to the code. In the TraverseFileContent.java class, I'm traversing this lines collection, this array list of strings representing the contents of a file, twice. In first version, starting at line 51, I'm using a forEach loop, it's a simple bit of code, and it creates a line String variable for each item in the list and then executes whatever code is needed.

At line 58, I'm using another approach, calling the iterator method of the collection. Getting an iterator object and then looping with a while code block, calling the iterators has next method. Now both of these bits of code have worked fine going all the way back to Java 5, but I'll show you what this might look like with a lambda expression and the forEach method. In Java 8, I'll start with this forEach method.

Starting at line 65 I'll reference my lines collection and call the new forEach method. And again it's going to receive an instance of the Consumer interface. Because Consumer is a functional interface, I can use a lambda expression. The Consumer interface's accept method requires a single argument of the appropriate data type. Because lines variable is declared as a list of strings, I have to pass in a string as the argument.

I'll pass it in with a name of line. Then I'll add my lambda operator, the arrow token. And I'll add my system output here, and pass in line.

And you can clean up the code a bit by removing old traversals. And now this single line of code replaces the three lines of the forEach loop. I'll make a copy of this code and move down here to the version that's using an iterator. And I'll select those lines of code and comment them out. And paste in my lambda expression version. So when you replace an iterator, you're replacing four lines of code with a single line.

More advanced you can use Stream with collections, Streams supports a sequence of elements supporting sequential and parallel aggregate operations. Normally it is used as the following:

Now save and run the code and see that it behaves exactly the same as it did before, but just with less code. So this is just another option for traversing collections. You can use forEach loops. You can use iterator objects and now you can use the forEach method with a lambda expression.

2- Filtering collections with predicate interfaces.

In addition to the new lambda syntax, Java SE 8 adds a number of new functional interfaces. One of the most useful is called the Predicate Interface. An interface that has a single boolean method named test, which you can use to wrap up your conditional processing, and make conditional code a lot cleaner. I'll show you how to use the predicate interface in this project.

Starting in the class named FileDirFilter class in package eg.com.tm.java8.features.lambda2.predicate, I've declared a method called predicateInInnerClass.

I will use NIO.2 DirectoryStream class, to get a specific path entries stream, which in our case is declared as:

Now my goal is to filter this stream and only display certain entries, which are directories. You can use the predicate interface either with inner class syntax or with lambda syntax.

I'll start with inner class syntax. In predicateInInnerClass method, I'll declare an instance of the predicate interface. I'll type the name of the interface and press Ctrl+Space. And choose the interface from the list. It's a member of the package Java.util.function, and you'll find a lot of other new functional interfaces there as well. This interface needs a generic type declaration. I'll set that to the name Path class. And I'll name the predicate, dirsFilter.

Now, for inner class syntax, I'll start with the new keyword, and I'll press Ctrl+Space and choose the constructor for the predicate interface. When I choose that, NetBeans automatically implements the single abstract method, test. Because I declared my predicate with a generic type of Path, the test method accepts a single argument of that type as well. Now, I'm going to implement the method. I'm going to change the name of the path object being passed in to just "t".

I'll set the return statement to use a very simple criteria. I'll add a set of parentheses to wrap my condition. And I'll set the condition to isDirectory(t, NOFOLLOW_LINKS). So now my predicate object encapsulates my test, and the test method can be used to determine whether I want to process an object from my collection.

The next step is to traverse the collection. And you can do this in a number of ways with a forEach loop, an iterator object, or with the new forEach method.

I'll use the classic forEach loop. I'll type foreach and press Ctrl+Space, and choose the foreach code template. Within the for loop, I'll use an if statement. And I'll set the condition to use the dirsFilter object that I just declared. I'll call dirsFilter.test. I'll pass in the file object that I'm declaring in foreach loop. And then if the condition is true, I'll use system output and I'll output the results of calling the getFileName method of the file object.

I'll save and run that code. And I only see full path of paths of type directory. Now, if I want to change my condition, I can change the predicate object and rerun the code and it'll work fine. But our goal here is to make the code as concise and readable as possible. And for that, you might decide instead to use a lambda expression to implement this predicate interface. So let's go back to the code, and I'll fold this method, predicateInInnerClass, and unfold other method, predicateWithLambda.

Now I'm going to do very similar processing. But I'll declare my predicate object this time using a lambda expression. Once again, I'll type the name of the interface. I'll press Ctrl+Space and choose it from the list, and set its generic type. And I'll name this predicate object noFilter. Now I'll implement the interface using a lambda expression. I'll start with the signature of the method I'm implementing. That's the test method. And because I declared predicate with a generic type of Path, the argument is going to be an instance of path.

I'll just name it p. Then I'll add the arrow token, and then I'll implement my method with a simple conditional expression, to true to just return all defined path entries. And that's all I need. This single line of code replaced five or six lines of code in the inner class version. Next, I'll loop through the list and use the test method of the predicate object. This time, I'll use the doFilterAndPrintPath method passing in my predicate noFilter.

I showed how to use this method in previous lambda implementations. It's a new method that was added in Java SE 8. In implementation of doFilterAndPrintPath method I am using the forEach method of newDirectoryStream returned collection of paths, I'll start with the name of the object I'm passing in as an argument. This time I won't wrap it inside parentheses just to show you a difference in syntax. Then I'll add the arrow token and a pair of braces. Within the braces I'll use an if statement. And I'll pass in my condition, which again the predicate's test method. I'll use pred.test, and I'll pass in the path object.

And if the condition is true, I'll use system output. And I'll output the path object file name. I'll save and run the code. And there is the result. Once again, I'm displaying all entries. But what if I want to deal with more than one possible condition? Well this is the great thing about lambda syntax and the predicate interface.

You can make as many predicate objects, as you want, each representing a different condition.

So I'm going to duplicate this line of code, and I'll change the name of the new one to hiddenFilter. And I'll change its condition to show only hidden files and directories. To make it really easy to pass in whichever predicate I want, I'll take this code that's traversing the collection, and put it into its own separate method. We already did that in doFilterAndPrintPath method.

Now, the method doesn't know which predicate it's going to get, so I'm refactored the name of the predicate object in the method to just pred. And now, my existing code is passing in hiddenFilter, so I'll run that. And I get all hidden files and directories. And then I’ll change the predicate object that I’m passing in to timeFilter, and I’ll run the code again.

And this time I get all files and directories that is modified today. So this is how you can use the new predicate interface and lambda expressions to encapsulate your conditions in individual objects. And then pass those objects into your own methods for processing.

I won't cover a lot of the other new functional interfaces in Java SE 8 in detail, but I encourage you to investigate the package that the predicate interface is a part of java.util.function. You'll find a lot of new useful interfaces there.

And because they're all functional interfaces, they can all be implemented with lambda expressions.

3- Traversing collections with method references.

In addition to Lambda expressions, Java SE 8's Project Lambda also adds method references to the language. A method reference gives you a way of naming a method you want to call, instead of calling it directly. And just like Lambda expressions, the goal is to make your code more concise and more readable.

I'll demonstrate this in this class named MethodReference under package eg.com.tm.java8.features.lambda2.mthdRefs.

You can use method references on four kinds of methods:

  1. Static methods of any class.
  2. Instance methods of a particular object.
  3. Instance methods of an arbitrary object, in which case you would refer to it just like it was a static method.
  4. And references to constructor methods.

I'll start with static methods. In this code, I have a FilesDirTests class, and my goal is to check wither a specific file is accessible or not. I'm going to create a method that does some comparisons to a path class. Now you could put this method anywhere you like, and developers will differ about the best place to put it, but I'm going to create the method as a static method of my FilesDirTests class.

I'll open the class and I'll place this new method. I'll declare it as public and static, and set its return data type to boolean. I'll name the method isAccessible. And the method will accept reference to path class. I'll name it p. This method will know that the goal is to compare path against some accessibility methods defined in java.nio.file.Files class. And just like the test method of the Predicate interface, this will return a true if the path is accessible, or false to indicate that path is not accessible.

I'll save that change, and now I'll go to my class MethodReference. To test accessibility of a given path files, I once again use the doFilterAndPrintPath(Predicate<Path> pred) method. I'll call it inside doPrint method. The defined path is used inside doFilterAndPrintPath method. And for the predicate object, I'll use a method reference. It'll look like this, I'm referring to a static method, and so I’ll start with the type, the class that contains the static method.

Then I'll put in the double colon operator, that's how you separate the type or the object from the name of the method that you're calling. And then I'll pass in the name of the method, isAccessible. Now here's why this is working. This method, the doFilterAndPrintPath method, is expecting an instance of the predicate interface. That interface has a single abstract method, which expects one value. I'm calling a method that expects one value. And returning a data type that can be used by the test method.

The doFilterAndPrintPath will traverse the path files, and output the values according to the test. Save the change, and run the code, and there's the result. Opppps There is no result? No files printed? This is because isAccessible has test condition that will make the test fails, which is isExecutable method.

So that's a static method reference. If you prefer, you can use method references with instance methods. To do this, I'm going to go down at the end of MethodReference class and add the following two methods:


In this class, in the main method, I'm creating an instance of the current class, and then calling it doFilterAndPrintPath method. By the time I get down here, all of the data and the methods are instance members, rather than static members.

Because main is a static method, so we can’t use this keyword, as alternative syntax you can use this keyword as reference inside object instance methods.

And just as I did before, I'll save and run, and there's the result. So method references are a simple way of making your code incredibly concise.

4- Implementing default methods in interfaces.

Prior to Java SE 8, interfaces could contain abstract methods and constant declarations, but you couldn't provide fully implemented methods that would be inheritable.

I'm working in a package called eg.com.tm.java8.features.lambda2.defltMthd. And in this application, I have an interface named VehicleInterface.Java. It has eight abstract methods, in interfaces all abstract methods are soon to be public, so I haven't included the public keyword and these are basic getters and setters.

Then I've a class named Car.java and this class has the setters and the getters implemented. And a constructor method that makes it easy to instantiate the class.

And then I have a main class called DefaultMethod.java. In this code, I'm filtering a list of cars using a predicate object, and then, display cars. I'm putting together a string named info and outputting it to the console. So, I'm going to refactor this code using a new capability of Java SE 8 that lets me add something called a default method to an interface.

When you add a default method to an interface, you can add its full implementation. And then, any class that implements that interface will inherit that method and you can call it itself or the method will be callable from anywhere else in the application because, just like the abstract methods, it will be public.

Back to VehicleInterface.Java I'll move the cursor below the abstract methods. And I'll start my method signature with the new keyword, default. The rest of the method will look exactly the same, as if I were implementing it in a class.

I'll start with the return type, then the name of the method. Next, I'll add the code, and it'll be a return statement that can concatenate the values of the name, model, car CC and the make year. Now, because this is an interface, I can't refer to private fields. You can't do that.

So, I'm just going to refer to the abstract methods, which I know will be implemented by the class itself. I'll call getName, getModel, getCC. Then I'll concatenate getMakeYear and a closing parenthesis.

I'll save that change and now that method is available to every class that implements the interface. I won't make any changes to the Car class. It already has that method. Then I'll go over here to my main class, use default method, and I'll change this code. I no longer need to create the string named Info, that's going to be done by the new method that the Car class has inherited. So, I'll comment out that line of code. And I'll replace the reference to the info variable with a call to the getInfo method.

But I'll call it as a member of the car object that I'm working with right now. I'll save the change and run the code. And there's the result. I'm successfully calling the getInfo method to get a string, a concatenation of the values of the name, model, CC and make year, and then I'm outputting it to the console using the code in my main class.

By using default methods, you can sometimes eliminate a whole layer of inheritance. Some developers, for example, in earlier versions of Java, might have created an interface, then a base class that implemented the interface and then a subclass that they would actually use in their code.

With this new capability, you might not need the base class at all and instead, can go directly to implementing the subclasses, inheriting the default methods directly from the interfaces.

5- Implementing static methods in interfaces.

I previously described how to add default methods to interfaces, which are fully implemented and are inherited by implementing classes. In Java SE 8, you can also add fully implemented static methods to interfaces. Just as with default methods, the goal is to let you eliminate inheritance layers and simplify your applications.

I'm working in a package called eg.com.tm.java8.features.lambda2.staticMthd. Just as in the earlier project, the one for default methods, the main class, which is called StaticMethod here, has code that gets the name, model, CC and make year from a car object.

It's at line 47 in this class. My goal is to take this code and move it to a static method, but instead of adding it to a base class or other concrete class, I'm going to add it to an interface. Something I wasn't able to do in earlier versions of Java. I'll take this code and copy it to the clipboard. Then, I'll open the interface, named VehicleInterface.java. Just as before, I'm starting with a set of abstract method declarations. Now, I'll place the cursor after those abstract method declarations and I'll start with the keyword static.

Just as with the default method and the abstract methods, this will be a public method automatically. I don't need to declare it. It'll return a string and I'll name it getVehicleInfo. Now because this is a static method, it can't refer to the instance methods declared above. So, I'm going to pass in an instance of the Car object. Then I'll provide the return keyword and I'll paste in the code from before and I'll clean this up so that now I'm returning the name, model, CC and make year and the closing parenthesis.

Now this static method is available from anywhere in the application. Just as before, I don't need to do anything to my Model class. That's called car, because all the code that's going to be getting the string and outputting it, is already available in the interface.

I'll go back to my main class, use static method, and now, instead of putting together this string here, I'll call the interface using the interface's name, VehicleInterface.java, then I'll call the new static method, getVehicleInfo and pass in the Car object, which is c.

And I'll save the change and run the code. And there's the result. Functionally, it's exactly the same as using a default method, or putting this code into the Car class, or having it right here at the top level in the main class.

The goal of both default and static methods is just to give you more options in putting together the inheritance model for your application. Using both default and static methods, you can eliminate entire inheritance layers of your application and enormously simplify the coding model, making the application easier to code and to maintain.

Resources:
  1. The Java Tutorials, Lambda Expressions
  2. JSR 310: Date and Time API
  3. JSR 337: Java SE 8 Release Contents
  4. OpenJDK website
  5. Java Platform, Standard Edition 8, API Specification