Java 8 was released on 18th March 2014. That’s a long time ago but still many projects are running on Java 8. It’s because it was a major release with a lot of new features. Let’s look at all the exciting and major features of Java 8 with example code.
Some of the important Java 8 features are;
Let’s have a brief look on these Java 8 features. I will provide some code snippets for better understanding the features in a simple way.
Whenever we need to traverse through a Collection, we need to create an Iterator whose whole purpose is to iterate over, and then we have business logic in a loop for each of the elements in the Collection. We might get ConcurrentModificationException if the iterator is not used properly.
Java 8 has introduced forEach method in java.lang.Iterable interface so that while writing code we focus on business logic. The forEach method takes java.util.function.Consumer object as an argument, so it helps in having our business logic at a separate location that we can reuse. Let’s see forEach usage with a simple example.
The number of lines might increase but forEach method helps in having the logic for iteration and business logic at separate place resulting in higher separation of concern and cleaner code.
If you read forEach method details carefully, you will notice that it’s defined in Iterable interface but we know that interfaces can’t have a method body. From Java 8, interfaces are enhanced to have a method with implementation. We can use default
and static
keyword to create interfaces with method implementation. forEach method implementation in Iterable interface is:
We know that Java doesn’t provide multiple inheritance in Classes because it leads to Diamond Problem. So how it will be handled with interfaces now since interfaces are now similar to abstract classes?
The solution is that compiler will throw an exception in this scenario and we will have to provide implementation logic in the class implementing the interfaces.
Notice that both the interfaces have a common method log() with implementation logic.
As you can see that Interface1
has static method implementation that is used in MyClass.log()
method implementation. Java 8 uses default and static methods heavily in Collection API and default methods are added so that our code remains backward compatible.
If any class in the hierarchy has a method with the same signature, then default methods become irrelevant. The Object is the base class, so if we have equals(), hashCode() default methods in the interface, it will become irrelevant. That’s why for better clarity, interfaces are not allowed to have Object default methods.
For complete details of interface changes in Java 8, please read Java 8 interface changes.
If you notice the above interface code, you will notice @FunctionalInterface annotation. Functional interfaces are a new concept introduced in Java 8. An interface with exactly one abstract method becomes a Functional Interface. We don’t need to use @FunctionalInterface annotation to mark an interface as a Functional Interface.
@FunctionalInterface annotation is a facility to avoid the accidental addition of abstract methods in the functional interfaces. You can think of it like @Override annotation and it’s best practice to use it. java.lang.Runnable with a single abstract method run() is a great example of a functional interface.
One of the major benefits of the functional interface is the possibility to use lambda expressions to instantiate them. We can instantiate an interface with an anonymous class but the code looks bulky.
Since functional interfaces have only one method, lambda expressions can easily provide the method implementation. We just need to provide method arguments and business logic. For example, we can write above implementation using lambda expression as:
If you have single statement in method implementation, we don’t need curly braces also. For example above Interface1 anonymous class can be instantiated using lambda as follows:
So lambda expressions are a means to create anonymous classes of functional interfaces easily. There are no runtime benefits of using lambda expressions, so I will use it cautiously because I don’t mind writing a few extra lines of code.
A new package java.util.function
has been added with bunch of functional interfaces to provide target types for lambda expressions and method references. Lambda expressions are a huge topic, I will write a separate article on that in the future.
You can read complete tutorial at Java 8 Lambda Expressions Tutorial.
A new java.util.stream
has been added in Java 8 to perform filter/map/reduce like operations with the collection. Stream API will allow sequential as well as parallel execution. This is one of the best features for me because I work a lot with Collections and usually with Big Data, we need to filter out them based on some conditions.
Collection interface has been extended with stream() and parallelStream() default methods to get the Stream for sequential and parallel execution. Let’s see their usage with a simple example.
If you will run above example code, you will get output like this:
Notice that parallel processing values are not in order, so parallel processing will be very helpful while working with huge collections.
Covering everything about Stream API is not possible in this post, you can read everything about Stream API at Java 8 Stream API Example Tutorial.
It has always been hard to work with Date, Time, and Time Zones in java. There was no standard approach or API in java for date and time in Java. One of the nice addition in Java 8 is the java.time
package that will streamline the process of working with time in java.
Just by looking at Java Time API packages, I can sense that they will be very easy to use. It has some sub-packages java.time.format that provides classes to print and parse dates and times and java.time.zone provides support for time zones and their rules.
The new Time API prefers enums over integer constants for months and days of the week. One of the useful classes is DateTimeFormatter for converting DateTime objects to strings. For a complete tutorial, head over to Java Date Time API Example Tutorial.
We have already seen forEach() method and Stream API for collections. Some new methods added in Collection API are:
Iterator
default method forEachRemaining(Consumer action)
to perform the given action for each remaining element until all elements have been processed or the action throws an exception.Collection
default method removeIf(Predicate filter)
to remove all of the elements of this collection that satisfy the given predicate.Collection
spliterator()
method returning Spliterator instance that can be used to traverse elements sequentially or parallel.replaceAll()
, compute()
, merge()
methods.Some important concurrent API enhancements are:
ConcurrentHashMap
compute(), forEach(), forEachEntry(), forEachKey(), forEachValue(), merge(), reduce() and search() methods.CompletableFuture
that may be explicitly completed (setting its value and status).Executors
newWorkStealingPool()
method to create a work-stealing thread pool using all available processors as its target parallelism level.Some IO improvements known to me are:
Files.list(Path dir)
that returns a lazily populated Stream, the elements of which are the entries in the directory.Files.lines(Path path)
that reads all lines from a file as a Stream.Files.find()
that returns a Stream that is lazily populated with Path by searching for files in a file tree rooted at a given starting file.BufferedReader.lines()
that return a Stream, the elements of which are lines read from this BufferedReader.Some miscellaneous API improvements that might come handy are:
jjs
command is added to invoke Nashorn Engine.jdeps
command is added to analyze class filesThat’s all for Java 8 features with example programs. If I have missed some important features of Java 8, please let me know through comments.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
thanks a ton man, awesom tutorial :)
- chandan kumar
Very good stuff man, really i’m very happy that i gained many things in java from you!!!
- Sathy\narayanan
Stream parallelStream = (Stream) myList.parallelStream(); In integer place i am getting error like: change project compliance and jre to 1.5. this erroe is coming in every integer place in code. p --> p > 90)----here showing create local variable,create field ,parameter wht i should do? for(int i=0; i<100; i++) myList.add(i);—here in add its error lke chang to AddAll()…wht should i do?
- sifun nanda
Awesome contents !! please keep helping us the same way !
- Rajiv
Really Nice & very useful stuff, But need to provide the examples for the 6 and 7th features.
- Nari Chinni
I have already listed the important new methods in the Collection and Concurrency APIs with brief explanation, just use them and it should be easy to go.
- Pankaj
Nice article… You explained really well… Thanks and keep it up…
- Nakul Shinde
Very good stuff man, really helping and to the point!
- Tayyab
Thanks a lot…Really beneficial
- Nobi Y
Good explanation. I would like to know the differences between Future and CompletableFuture
- babita
can you explain little more about FuctionalInterface and functional programming 1.what is functional programming ?why .explain with real time scenario 2.what is functional Interface and what purpose it has been introduced in java and what we can achieve with functional Interface 3.without functional interface what we cant achieve in java 8?
- Prabu
// forEach example to print each element of list // in this case we are using method reference becasue // we are not doing anything with each element of collection // and just passing ito println method System.out.println("Printing elements of list using forEach method : "); listOfPrimes.stream().forEach(System.out::println); // let’s do something to each element before printing // we will add comma after each element System.out.println("Printing elements after adding comma: “); listOfPrimes.stream().forEach( i -> System.out.print( i + “,”)); // you can also use forEach with parallel stream // order will not be guaranteed System.out.println(”\nPrinting elements of list using parallel stream: "); listOfPrimes.parallelStream().forEach( i-> System.out.println(i*2));
- dhrumil
Nice article on java 8 new features. Thanks a lot.
- prabhath
Nice article keep it up
- Ravi
New features explanation is very nice. Thanks a lot. Keep it up
- Kailash CH Das
Your understanding of java technologies are helping lot of people…Thanks a lot.
- AMIT BANSAL
Nice article
- Chintan Kansara
very nice
- ganesan
Good Article
- Manoj
Thanks for this valuable Article
- hitesh
Simply superb!!!
- Venkat
Nice explanation for new features added in Java 8
- Jayhind Rajpoot
great tutorial
- neha
Nice article.Brief and to the point.
- Deepak Shah
A beautiful Updation
- Debendra Dhinda
Nice explanation of Java8 features.
- Ranga
Very clear explanation with samples. But contrary to you - there is benefit when using Lambda. In normal anonymous class implementation, new .Class files are created where as with Lambda no new .Class files are generated.
- Dhanya
Hi Pankaj, very good article on Java8 and please provide me more information on the following topic of Java8. *******Collection API improvements**** if you provide more information it would be great help for all those whose are reading this article. thanks in advance Pankaj. Sr. Software Engineer @ Tech Mahindra.
- Pradeep Kumar
Nice tutorial.
- Rajesh
Good explanation
- Bharath
interface MyInt1{ default void log() { System.out.println(“this is log file interface”); } } interface MyInt2{ default int log() { System.out.println(“hai this is another interface”); return 10; } } public class FunctInterface implements MyInt1,MyInt2{ public static void main(String[] args) { FunctInterface f=new FunctInterface(); f.log(); } //throws error please tell me how to solve @Override public void log() { // TODO Auto-generated method stub MyInt1.super.log(); } }
- krishna
In the both interfaces method return type should be same.
- kammiti krishna
Guys Functional programing are Already there in SCALA Language
- BASAVARAJ
Hello Sir, Could you please justify the statement “Performance Improvement for HashMap class with Key Collisions”.? How they have improved the HashMap class with Key Collisions?
- Mayur Patel
In Java 8 we have below changes, in case of collision till Java 7 it used to store values in linked list and the search order for link list is O(n), but in java 8 it forms binary tree (O(log(n))) instead of linked list. This makes search faster, this would be useful in case of billions of records getting collide for same hash key.
- Dileep
Prior to Java 8 collision results in a list structure at the bucket where as java 8 changes that implemention to tree
- Anand
Is it me or these new features are turning the language into unreadable mess
- jdk1.7
It’s very useful to know overview of new features of Java 8 in less time.
- Raj Rusia
Simply superb
- Narendra b
Good Article, Thanks a lot…
- Krishnan K
Very helpful. I’m very grateful to see such topics discussed here.
- Harry S. Green
You can override default interface. It wont complain.
- Arvind
In forEach example, MyConsumer should be static inner class not just inner class if we want to use that in main().
- Rama
Pankaj, I guess when you say “Make sure your projects build patch is using Java 8 library.” you mean build path, right?
- Valentino
Yes, build path. corrected it.
- Pankaj
Thank you!
- Tomasz Krzysztof
You can also discuss about method reference in this tutorial. Method reference is also a very important feature in Java 8
- Nitin
It’s good to know but it’s just to reduce number of lines of code.
- Pankaj
Thanks a lot Pankaj. A very concise and self explanatory info and that too at a one place. :)
- Ajeet Patel
You are welcome Ajeet, appreciate the kind words.
- Pankaj
Thanxxxxxxxxxxx Pankaj , You saved my day , All information at one place … Thnxxx again :)
- Gaurav Jain
tnx. very nice
- hashem yousefi
wonderful information , And easy to understand
- Thirupathi
Thanks for the consolidate information and even links for elaborations :)
- Mithila
Rest of the stuff was REALLY useful but lambda was the lamest people wrote entire books about why lambda expressions are elegant and useful and all you can say is I dont mind extra code? really?
- kalpesh soni
Could you show me an example where lambda expressions brings real benefits such as better performance (like StringBuilder brings over StringBuffer)? Ultimately lambda expression reduces the code size and if not used wisely, it could get messy. That’s why I mentioned that if you are not too familiar with it, better go with the basics even if it cause few extra lines of code. I use it in my code but not all the time, I am still not comfortable with “method reference” (::) and still write System.out.println rather than System.out::println.
- Pankaj
Lambda expression allowed us functional programming rather than reduces the code. “System.out.println vs System.out::println.”
- Rahul kumar
Because of functional programming when we compile code in java 8, there will be only one .class and no sub-class while in previous versions it creates sub-classes for anonymous classes.
- Ravi
Nice and easy-to-follow article about main java 8 features. Thank you.
- Abdulaziz
Thank you for sharing . Please keep it up.
- Ahmad Sayeed
It was a great help.
- Jyoti Namdeo
Here are some features of Java 8: 1. Implementation of Lambda expressions. 2. Date and Time API. 3. A lightweight, high performance implementation of JavaScript engine is integrated to JDK. 4. Improved Security
- Mridula
Static methods in Functional Interface . @FunctionalInterface interface MyFunctionalInterface { public int addMethod(int a, int b); static void method1() { System.out.println(“Static method1 implementation”); } static void method2() { System.out.println(“Static method2 implementation”); } } public class StaticMethodDemo implements MyFunctionalInterface{ /** * By default static methods are not available to implementation class . * So no overriding . * */ static void method2() { System.out.println(“Static method2 implementation”); } public void method1() { System.out.println(“Instance method1 implementation”); } private static void method3() { System.out.println(“Static method3 implementation”); } public static void main(String[] args) { MyFunctionalInterface.method2(); } @Override public int addMethod(int a, int b) { // TODO Auto-generated method stub return 0; } } Few points on Static Methods in Interface with Java 1.8 General utility methods are to be added as static methods in interface which are not related to Object State The methods can be called with Interface name not implementation object reference or implementation class name Not available by default to implementation class Overriding not applicable for interface static method as it is not available by default to implementation class Main method can be declared inside interface . Can execute main method inside interface .
- Rumpee
Also, the HashMaps now use a Tree instead of a LinkedList when number of linked nodes cross a threshold. The default TREEIFY threshold is 8, and default UNTREEIFY threshold is 6. This means, when number of nodes cross 8 a tree structure would be formed and if you remove nodes the tree structure would change after it reaches 6.
- Ashish Balani
okk but i think new version
- BALAGURIAH
Don’t we all, Balaguriah? Don’t we all…
- Pankaj
Among them, I think stream, time and lambda expression API are the best features. Thanks to #pankaj for this awesome tutorial.
- Md. Ahsan Kabir
Thanks a lot Pankaj for the wonderful article.
- Meghala Devi
very good to read.good analysis. thanks m pankaj
- vellai varanan
Jcmd for thread dump in java8
- Ravi Gupta
u have java 8 dumps ?
- Manikanta Sanambatla
Thanks for great tutorial
- Sudhakar
Nice article! Keep up the good work :)
- Snehasish
Very interesting article, Explanation are very good with examples
- Sangumithra Ashokan
I often visit your website to keep updated. I am java dev as well as a blogger. However, I am a completely new bee in the blogging field. I have noticed one thing and also wanted to let you know. Every time I see your highlighted word, I just wanted to see them with some paddings.
java.util.stream
Hope You will understand What I mean.- UnboxHow
Very useful and Informative article. Thanks for posting it.
- Krishna Mohapatra
Great article, but the highlighting of sentences is not very user friendly with this dark highlighting over black text.
- chsdk
Thanks for the article, clear and easy examples. When migrating my project from Java-7 to Java-8, can you suggest what are the things I should look into ? Some features might be obsolete and some might got removed in Java-8.
- Mani Raman
The new method in Iterator interface is forEachRemaining and not forEach.
- Divya Gupta
before Apr 2014 you posted this valuable information about Java8, Really Incredible man … thanks Pankaj
- kuladeep patil
Hi Pankaj Ji, I am not able to install java version 8 in linux mint for SAP Gui support i am try to install but java packeg is not abelable in below commands $sudo add-apt-repository ppa:webupd8team/java $sudo apt-get update $sudo apt-get install oracle-java8-installer $ java -version java version “1.8.0_201” Java™ SE Runtime Environment (build 1.8.0_201-b09) Java HotSpot™ 64-Bit Server VM (build 25.201-b09, mixed mode)
- Shanu
hahsmap internal working has been changed from java 8. If number of keys with same hashcode exceeds a value, internally values are stored in binary tree than linked list.
- vinay
(s) -> System.out.println(s); in above statment if its one parameter no () parantasis required. you can write s->System.out.println(s); method ref; System.out::println
- Jeelan Yelidandla
Hi Pankaj, While I was practicing the forEach() I got concurrent modification exception. As you have explained, before java 8 version we used to get concurrent modification exception if we don’t use iterator properly. One of the Java 8 feature forEach() solves the problem but I got concurrent Exception with forEach(). Please find the below code which throws the Exception. public class ForEachTFeatureTest { public static void main(String[] args) { List myList = new ArrayList(); myList.add(1); myList.add(2); myList.add(1); myList.add(3); myList.add(1); myList.forEach(new Consumer() { public void accept(Integer t) { if(t == 1){ myList.remove(t); } System.out.println(“forEach anonymous class Value::”+t); } }); } } Is my understanding bout forEach() is proper?
- Anusha