Java 8 Top Tips

I’ve been working a lot with Java 8 code over the last couple of years, for both new applications and migrating existing ones, and it feels like the right time to write down some of the “best practices” I’ve found useful. I personally dislike the term “best practices” as it implies a “one size fits all” solution, and of course coding doesn’t work that way – it’s down to us as developers to figure out what will work in our situation. But I have discovered I have particular preferences for Java 8 code that I find makes my life a little easier, and I thought I’d start a discussion on this topic.


Optional is a highly underrated feature, and one that has the potential to remove a lot of those NullPointerExceptions that can plague us. It’s particularly useful at the boundaries of code (either APIs you’re using or APIs you’re exposing) as it allows you and your calling code to reason about what to expect.

However, applying it without some thought and design can lead to one small change impacting a large number of classes, and can lead to poorer readability. Here are some tips on how to use Optional effectively.

Optional should only be used for return types
…not parameters and not fields. Read this blog post to see a pragmatic approach to using Optional. Fortunately, IntelliJ IDEA lets you turn on an inspection to check you’re following these recommendations

Optional Parameter Warning

Optional values should be dealt with in the place they’re encountered.  IntelliJ IDEA’s suggestions will prevent Optional leaking all over your code, so remember you should deal with Optional where you found it and move swiftly on.

Deal with Optional immediately

You should not simply call get()
The strength of Optional is to express that this value might be empty, and allow you to cater for that case. Therefore, it’s important to check if there is a value before doing anything with it.  Simply calling get() without checking isPresent() first is likely to lead to a null pointer at some point. Fortunately, once again IntelliJ IDEA has an inspection to warn you to stick to this.

Get without isPresent

There is probably a more elegant way
The isPresent() combined with get() certainly does the trick…

Simplest use of Optional

…but there are more elegant solutions. You can use orElse to give an alternative value in the case that it’s null

Using Optional orElse

…or you can use orElseGet to tell it which method to call in the case that the value is null. This might seem the same as the above example, but the supplier method will be called only if needed, so if it’s an expensive method, using the lambda will give you better performance.

Using Optional orElseGet

Using Lambda Expressions

Lambda expressions were one of the main selling points of Java 8.  Even if you’re not using Java 8 yet, you’ve probably got basic understanding of them by now. But they are a new way of programming within Java, and it’s not yet obvious what is “best practice”. Here are some guidelines I like to follow.

Keep it Short
Functional programmers may be happy with longer lambda expressions, but those of us who’ve been using only Java for many years might find it easier to keep lambda expressions to a small number of lines. You might even prefer to limit them to just a single line, and you can easily refactor longer expressions into a method.

Extract longer lambda expressions into methods

These may even collapse down into method references. Method references may seem a bit alien at first, but it’s worth persevering with them as they can actually aid readability in some cases, which I’ll talk about later.

Collapse Lambda to Method Reference

Be Explicit
Type information is missing for lambda expressions, so you may find it useful to include the type information for the parameter.

Explicit parameter types for lambda expressionsAs you can see, this can get quite unwieldy.  So I prefer to give my parameters a useful name. Of course, whether you do this or not, IntelliJ IDEA lets you see type information of parameters.

See the parameter types of the lambda

and even the Functional Interface the lambda represents

See the lambda's functional interface

Designing for Lambda Expressions

I think of lambda expressions as being a little like Generics – with Generics, we use them regularly (for example, adding type information to List<> ), but it’s much more rare that we’ll design a method or a class that has a Generic type (like a Person<T>). Similarly, it feels like we’ll pass lambdas around when using things like the Streams API, but it’ll be much more rare for us to create a method that requires a lambda parameter.

However, if you do find yourself in this situation, here are some top tips.

IntelliJ IDEA can help you introduce a functional parameter
This lets you create a parameter where someone will pass in a lambda rather than an Object. The nice thing about this feature is that it suggests an existing functional interface that matches the specification.

Extract functional parameter

Which leads to…

Use existing functional interfaces
As developers become more familiar with Java 8 code, we’ll know what to expect when using interfaces like Supplier and Consumer, and creating a home-grown ErrorMessageCreator (for example) could be confusing, and wasteful. Take a look at the function package to see what’s already available.

Add @FunctionalInterface to your functional interface
If you really do need to create your own functional interface, then tag it as such with this annotation.  It might not seem to do much, but IntelliJ IDEA will show you if your interface doesn’t match the exceptions for a functional interface. It flags when you haven’t specified a method to override:

Functional interface without a method

it flags when you’ve specified too many:

Functional interface with too many methods

and it warns you if you’ve applied it to a class rather than an interface:

Functional interface that's actually a class

Lambda expressions can be used for any interface with a Single Abstract Method, but they can’t be used for abstract classes that meet the same criteria.  Seems illogical, but it is what it is.


The Stream API is another one of the big selling points of Java 8, and I think we still don’t really know how much this is going to change (or not) the way we code. Here’s a mixed bag of things I’ve found useful.

Line up the dots
I personally prefer to line up my stream operations. You don’t have to, of course, but I’ve found this helps me:

  • see which operations I have, in order, at a glance
  • debug more easily (although IntelliJ IDEA does offer the ability to set breakpoints on any of multiple lambda expressions on a line, splitting them onto separate lines does make it simpler)
  • comment out an operation while I’m testing things
  • easily insert a peek() for debugging / testing

Line up your dots

Also it’s neater, in my opinion. But we don’t gain a lot in terms of reducing lines of code if we follow this pattern.

You may need to adjust your formatting settings to get the dots lined up.

Formatting Stream method chaining

Use Method References
Yes, it does take a while to get used to this weird syntax. But when used correctly, it really adds to the readability. Consider

Stream using a simple logical filter

verses the use of the helper methods on the (fairly) new Objects class:

Stream with method reference

This latter code is much more explicit about which values it wants to keep.  IntelliJ IDEA will usually let you know when a lambda can be collapsed to a method reference.

Use method reference instead of lambda expression

When iterating over a Collection, use the Streams API where possible
…or the new collections methods like forEach.  IntelliJ IDEA can suggest this to you:

Replace iteration with forEach

Generally using the Streams API is more explicit than a combination of for loops and if statements.  For example:

Using traditional iteration

IntelliJ IDEA suggests this can be refactored to:

Using the Streams API

The performance tests I’ve done show that this sort of refactoring can be surprising – it’s not always predictable whether performance will stay the same, improve, or get worse. As always, if performance is critical in your application, measure it before committing to one style over another.

Use for loops when looping over arrays
However, using Java 8 doesn’t necessarily mean you have to use streams and new collections methods everywhere. IntelliJ IDEA will suggest things that can be converted to streams, but that doesn’t mean you have to say “yes” (remember inspections can be suppressed or turned off).

In particular, iterating over a small array of primitive types is almost definitely going to be better performance with a for loop, and probably (at least while Java developers are new to streams) more readable.

For loops are faster over arrays

As with any of the tips, this rule is not set in stone, but you should decide whether you are going to prefer using the Streams API where you can, or whether you’re still going to use loops for some operations.  Above all, be consistent.


I’m discovering new things every day, and sometimes my preferences change – method references, for example, I used to hate, and avoided having them in my code. I’d love to hear your top tips!

Posted in Tips & Tricks | Tagged , | 5 Comments

IntelliJ IDEA 2016.2.1 EAP updates Kotlin support to 1.0.3

Great news! IntelliJ IDEA 2016.2.1 is on the horizon. You’re welcome to give its first EAP build a try. In addition to the usual dose of bugfixes, this EAP build updates the bundled Kotlin plugin version to 1.0.3. Here’s a little more insight into what it brings you.

If you’ve ever pasted Java code into a Kotlin file, you’ve probably noticed that IntelliJ IDEA offers to automatically convert it to Kotlin. However, this used to work only if the code was copied from inside the IDE. Now it works no matter where you got the code, even if it is a StackOverflow page.

Code completion for Kotlin also got better. IntelliJ IDEA suggests non-imported members and adds an import statement automatically on selection. Smart Completion is available after by and in statements.

The Move Element Left/Right actions, which were added earlier for Java, now work for Kotlin.

And finally, the Kotlin Bytecode tool window now has a Decompile button.

For more details read the announcement in the Kotlin blog.

As always, we appreciate your feedback here in the comments as well as in our issue tracker.

Develop with Pleasure!

Posted in EAP Releases, New Features | Tagged , , , | 1 Comment

Live Webinar: What’s New in IntelliJ IDEA 2016.2

We hope you’ve already tried IntelliJ IDEA 2016.2 which we released earlier this week. Even if you haven’t, we’re offering a deeper insight into its new features Wednesday, July 27th, 12:00 PM – 1:00 PM EDT (New York) / 18:00 – 19:00 CEST (Berlin) (check other time zones) during a live webinar What’s New in IntelliJ IDEA 2016.2, featuring Trisha Gee.


In this webinar Trisha will give you an overview of the most important changes of 2016.2 and, of course, will answer your questions.

Register now!

Speaking to you

Trisha GeeTrisha has developed Java applications for a range of industries, including finance, manufacturing and non-profit, for companies of all sizes. She has expertise in Java high performance systems, is passionate about enabling developer productivity, and dabbles with Open Source development. You can follow her on Twitter – @trisha_gee

The Drive to Develop

Posted in Webinars | Tagged , | Leave a comment

Java Annotated Monthly – July: Java Tools and Technologies

Whether you like to branch out into other JVM languages, or prefer to get deep knowledge in “classic” Java, there’s always more to learn in our Java-flavoured world.  This issue aims to give you some summer holiday reading. But the most exciting news this month is a double-whammy: IntelliJ IDEA is the top IDE, according to the latest Developer Productivity Report, and we have a new version of IntelliJ IDEA!


Continue reading

Posted in News & Events | Tagged | 5 Comments

IntelliJ IDEA 2016.2 is Here!

The last four months passed quickly, yet they were very productive. Today we give you IntelliJ IDEA 2016.2, our second update in the series of this year’s releases. As usual, it brings both useful new features and important fixes. Read on to learn what kept us busy and download the update to try all of its new features without any further ado.


Continue reading

Posted in New Features, Releases | Tagged , | 79 Comments

IntelliJ IDEA 2016.2 RC is Out

Time flies! The IDE update planned for this summer is now a matter of days. Today’s good news is that we’ve published its first RC build. You’re very welcome to download it and give a thorough try to all of its new features.

We appreciate your feedback on bugs and other flaws you may find in the build. Report them without hesitation to our issue tracker.

Develop with Pleasure!

Posted in EAP Releases, Release Candidates | Tagged , | 2 Comments

IntelliJ IDEA 2016.2 EAP Adds Breadcrumb for Java

Fresh IntelliJ IEA 2016.2 EAP build is out and ready. Among the usual bugfixes it also brings something special: Breadcrumbs for Java code.

Until now breadcrumbs were only available in HTML and XML code, where they have proven to be super handy for tracking of the editing position as well as traversing the tag tree. Now breadcrumbs work for Java, too, where instead of tags they let you navigate through classes, lambda expressions and methods:

To enable this feature, go to SettingsEditor → General → Appearance and select Show breadcrumbs.

Your thoughts and impressions about this and any other changes are very welcome here in the comments, and, of course, in our issue tracker.

Develop with Pleasure!

Posted in EAP Releases, New Features | Tagged , | 16 Comments

Webinar Recording: Refactoring with IntelliJ IDEA

Last week we had two exciting events: IntelliJ IDEA 2016.2 Public Preview announcement, and a webinar in which Bill Wake gave a one-hour masterclass on refactoring with IntelliJ IDEA.

The preview is definitely worth a try, so please help yourself to it (don’t forget to share your feedback, of course.) As for the webinar, you’re welcome to watch its recording any time:

Sources of the original Gilded Rose application can be found on GitHub, as are sources of the same application after all the refactoring.

To learn more about refactoring code and IntelliJ IDEA, read this article on DZone, and of course, check out the IntelliJ IDEA official page, for there are links to articles and tutorials on this topic.

And finally, you may want to have a look at Code Katas, a free interactive exercise by Industrial Logic, our Training & Consulting Partner. This exercise lets you practice Test-Driven Development, refactoring, and other programming skills in Java. Katas not only checks your stats, but also provides you with personalized feedback as you progress through it.

About the presenter

Bill WakeBill is best known in the Agile community as the creator of the INVEST model for user stories and the Arrange-Act-Assert guideline for unit tests. He has been an author of several books on XP, refactoring and design patterns. You can follow him on Twitter @wwake

Develop with Pleasure!

Posted in Tips & Tricks, Webinars | Tagged | 3 Comments

IntelliJ IDEA 2016.2 Public Preview

We’re excited to announce that IntelliJ IDEA 2016.2, the next IDE update awaited this summer, is now available for public preview! To get all the details about its new features and to download the preview build, proceed to our website.

Here’s a list of most notable changes:

  • Debugger
    • The Watches and Variables views in the Debugger tool window have been merged together.
  • VCS
    • The Log viewer for Git and Mercurial got faster and now has a handy loading progress indicator.
    • Patches are much easier to apply, especially if the files have been changed since the patch was created.
    • Case-only renames now work well in Git for Windows and OS X.
  • User interface
    • The Editor supports monospaced fonts with ligatures: e.g. FiraCode, Hasklig, Monoid or PragmataPro.
    • Any image can be set as the background of the Editor and the IDE Frame.
  • Spring Frameworks
    • Support for the Spring 4.3 and Spring Security 4.0 features.
    • Coding assistance for the Cache Abstraction.
    • Improved performance (for projects with many XML files; and several simultaneously opened projects).
  • JavaScript
    • Intentions to convert code to ES6.
    • Better coding assistance for React.
    • Smarter support for TypeScript’s enum types.
  • Database Tools
    • Code completion is now more context-aware.
    • Code completion for column values inside the Table Editor.
    • Better PostgreSQL support.
  • Android
    • Android Studio 2.0 features (except Instant Run, not fully merged yet).
  • Other
    • The Windows installer bundles a custom JDK with fixes for focus and font rendering issues.

Give it a try

You’re very welcome to download the preview build and give all its new features a spin. If you do, please do share your impressions with us here in the comments or directly in our issue tracker.

Develop with Pleasure!



Posted in Beta Releases, New Features | Tagged , | 4 Comments

How to Support Case-only Rename in Git

As you may know in IntelliJ IDEA 2016.2 EAP we’ve finally fixed a very annoying issue that didn’t allow to commit case-only renames in IntelliJ IDEA. For a number of reasons, the solution was not so trivial, we decided to share some of its implementation details with you.

When you are on a case-sensitive file system (Linux), case-only renames are just like any other renames, so you’re all good. However, when the file system you’re using is case-insensitive (like Windows or Mac), some of many Git commands will treat changing the file name case as a change, while others won’t. Because of that, a seemingly simple rename of “” to “” makes you face errors you clearly don’t expect. The nature of these errors is in that Git status remains the same, but most of the Git commands will not work with the new name, because the index and the repository still contain the old name.

Turns out that there’s an easy fix for this: just use git mv --force to perform a case-only rename. This will make Git see this rename as a change, and will record it to the index. Of course, we’ve implemented it, and now when you rename a file from IntelliJ IDEA, it will use this command to actually perform it.

However, that is only the tip of an iceberg. I’m not going to mention several places when we relied on system case-sensitivity settings for file paths comparison, which didn’t allow to put two case-only-different paths into a HashSet, and so on. :) Just had to do some debugging for a while and fix all these places.

Things got really interesting when we tried to commit these rename changes, which were already properly recognized by Git. In Git CLI, as well as in most of the clients, you just call git commit and commit everything that is staged. However, in IntelliJ IDEA we call git commit --only -- <paths> which lets commit only selected files, regardless of whether they are staged or not. This allows you, the user, to select paths from the UI and not think about Git indexes. This approach has, of course, a certain downside, but we are working on improvements, and are going, for example, to provide experienced users with a way to manipulate the Git index in the upcoming releases.

The problem here is that Git doesn’t allow the --only syntax for case-only renames, so git commit --only simply fails. We could call git commit without options and commit everything what’s in the index, but what if you’d like to exclude some files from that commit? We had several options on how to deal with these cases, and we decided to stick to the following procedure:

  1. Check what is staged besides case-only renames.
  2. Reset staged changes which are not selected for commit.
  3. Stage what else is needed to be commited.
  4. Commit the staging area.
  5. Stage back the changes unstaged before commit.

If you’re an experienced Git user, you might have noticed that there is a highly improbable case when this procedure will cause an issue: if you have a case-only rename, and you have a file that you don’t want to commit together with this case-only rename, and this file is both partially staged, and partially not-staged, and this separation is important to you (e.g. contains different sorts of changes), then the procedure above will make all changes in the file staged. However, we felt that it is nearly impossible case, and decided not to handle it until we have a GUI for Git staging area and the >git add -p feature.

Please note that as it was described in the beginning of the article, if you rename a file outside of IntelliJ IDEA (via the Terminal or from Finder or Explorer app) without properly calling git mv -f, you’re still doomed. Sorry for that, but that’s because Git won’t see the change at all, and it is not clear how to overcome this problem in IntelliJ IDEA. We are open for suggestions, and would like to implement them if they won’t affect performance or usability in ordinary situations.

Hope you’ll find IntelliJ IDEA helpful enough when you face a case-only rename. If you find any issues with the described approach, please report here or to the tracker.

Posted in New Features | Tagged , | 9 Comments