Contact Info

Jaded Studio

Thoreau Blvd.
O'Fallon, MO 63366
phone: 618.219.5249
email: send me accolades

Find Me On...


The Argument for Java 8

01 Jul 2016

Java 8 came out early last year—and Java 7 is now end of life—making Java 8 the only Oracle-supported option until Java 9 comes out at the end of next year. However, since organizations value stability over trendiness, many of us are still working with Java 7, or even 6. Let’s look at some features of Java 8, and provide some arguments to persuade your organization to upgrade.

It's faster

Here’s a selling point that might please your boss, the business, or the operations guys: you’ll probably find Java 8 runs your application faster. Generally speaking, applications that have moved to Java 8 see some sort of speed improvement without any specific work or tuning. This may not apply to an application that has been highly tuned to a specific JVM, but there are a number of reasons why Java 8 performs better:

Performance Improvements in Common Data Structures:
Benchmarks of the ever-popular HashMap show thatperformance is better in Java 8. These sorts of improvements are very compelling you don’t need to learn the new Streams API or lambda syntax or even change your existing code to get speed improvements in your application.
Garbage Collector Improvements:
Often “Java Performance” is synonymous with “Garbage Collection,” and it is certainly true that poor garbage collection performance will impact an application’s performance. Java 8 has substantial changes to GC that improve performance and simplify tuning. The most well-known of these changes is the removal of PermGen and the introduction of Metaspace.
Fork/Join Speed Improvements:
The fork/join framework was new in Java 7, and was the latest effort to simplify concurrent programming using the JVM. A lot of work went into improving it further for Java 8. Fork/join is now the framework that’s used under the covers for parallel operations in the Streams API (more on this later).

In addition, there are plenty more changes in Java 8 to support concurrency, and Oracle has summarized some of the performance improvements in JDK 8.


Java is regularly accused of being heavy on boilerplate code. Java 8 addresses some of these issues by embracing a more functional style for the new APIs, focusing on what you want to achieve and not how to do it.


Lambda expressions in Java 8 are not just syntactic sugar over Java’s existing anonymous inner classes—the pre-Java 8 method of passing behavior around. Lambdas take advantage of Java 7’s under-the-hood changes, so they perform well. To see examples of where using lambda expressions can simplify your code, read on.


While Lambdas and Streams (which we’ll cover next) are probably the top two selling points of Java 8, what’s less well known is that changes in Java 8 have allowed the language developers to add new methods to existing classes without compromising backwards compatibility. The result is that the new methods, combined with lambda expressions, allow us to drastically simplify our code. Take, for example, the common case of figuring out if an element already exists in a Map and creating a new one if not. Before Java 8, you might write something like:

    private final Map<CustomerId, Customer>
    customers = new HashMap<>();

    public void incrementCustomerOrders(CustomerId
    customerId) {
        Customer customer = customers.
        if (customer == null) {
            customer = new Customer(customerId);
            customers.put(customerId, customer);

This operation of “check if the item is in the map; if not, create it and add it” is so common that there’s a new method on Map to support it: computeIfAbsent. This method takes as its second argument a lambda that states how to create the missing item:

    public void incrementCustomerOrders(CustomerId
    customerId) {
        Customer customer = customers.
        id -> new Customer(id));

In fact, there’s another new feature in Java 8 called method references that makes this even shorter:

    public void incrementCustomerOrders(CustomerId
    customerId) {
        Customer customer = customers.
        computeIfAbsent(customerId, Customer::new);

Map and List both have new methods in Java 8. It’s worth checking them out to see how many lines of code they can save you.


The Streams API gives you flexibility to query and manipulate your data. This is a powerful tool. Building f luent queries for your data is interesting in a Big Data world, but is just as useful for common operations. Let’s say, for example, that you have a list of books and you want to get a list of unique authors for these books, in alphabetical order:

    public List<Author> 
    getAllAuthorsAlphabetically(List books) {
        List<Author> authors = new ArrayList<>();

        for (Book book : books) {
            Author author = book.getAuthor();
            if (!authors.contains(author)) {
        Collections.sort(authors, new Comparator() {
            public int compare(Author o1, Author o2) {
                return o1.getSurname().
        return authors;

In the code above, we first iterate through the list of books, adding the book’s author to the author list if it hasn’t seen it before; then we sort the authors alphabetically by surname. This is exactly the sort of operation that streams have been designed to solve elegantly:

    public List<Author>
    getAllAuthorsAlphabetically(List<Book> books) {
        .map(book -> book.
        .sorted((o1, o2) ->

Not only is this fewer lines of code, it’s arguably more descriptive a developer coming to this code later can read it and understand that

  1. it’s getting authors from the books,
  2. it’s only interested in unique authors, and
  3. the list that is returned is sorted by author surname.

Combine the Streams API with other new features—method references and new methods on Comparator—and you get an even more succinct version:

    public List<Author>
    getAllAuthorsAlphabetically(List<Book> books) {

Here it’s even more obvious that the sorted method orders by the author’s surname.


We spoke about better out-of-the-box performance, and in addition to those earlier mentioned features, Java 8 can explicitly make use of more CPU cores. By simply replacing the method stream in the examples above with parallelStream, the JVM will split the operation into separate jobs and use fork/join to run them on multiple cores. However, parallelization is not a magic incantation to make everything faster. Doing operations in parallel always requires more work—splitting up operations and recombining results—and will therefore not always take less time. But this option is very interesting for areas that are suitable for parallelization.


Another new feature of Java 8 is the new Optional type. This type is a way of explicitly stating “I might have a value, or I might be null.” Which means an API can now be explicit about either returning values that might be null vs. values that will always be non-null, minimizing the chances of running into a NullPointerException.

What’s nice about Optional is the way you tell it to deal with nulls. For example, if we’re looking for a particular book in a list, the new findFirst() method returns an Optional, which tells us it’s not guaranteed to find a value. Given this optional value, we can then decide what to do if it’s null. If we wanted to throw a custom Exception, we can use orElseThrow:

    public Book findBookByTitle(List<Book> books, 
    String title) {
        Optional<Book> foundBook =
        .filter(book -> book.getTitle().
        return foundBook.orElseThrow(() -> new
        BookNotFoundException(“Did not find book with
        title “ + title));

or you could return some other book:

    return foundBook.orElseGet(() -> getRecommendedAlternativeBook(title));

Or we could return an Optional so that callers of the method can make their own decision on what to do if the book is not found.


Java 8 was a big release for Java, with syntax changes, new methods and types, and under-the-cover changes that will help your application even if you don’t use the new language features. Java 7 is no longer supported by Oracle, so organizations are being pushed to migrate to Java 8. The good news is that Java 8 has many benefits for your business, your existing application, and for developers looking to improve their productivity.