Learn 7 Most Important Java8 Features with Easy Examples
It’s been a long time since Java 8 has been introduced. Java 9 and 10 are already becoming the talk of the town. So its time to learn Java 8 Features with some easy Examples.
Below are Most Important 7 Features we are going to learn in this article :
- Lambda Expressions
- Default Methods
- Date and Time API
- Streams
- forEach() Method
- Type Annotations
- Repeating Annotations
Lambda Expressions
one of the famous feature introduced in Java 8. Lambdas treat functionality as a method argument or code as data. Lambda expressions allow you to present your code more compactly.
For demonstration let us see a basic sorting example to check lambdas. Let us write a simple class to store some data for Employee:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Employee { private int id; private String name; private double salary; public Employee(int id, String name, double salary) { this.id = id; this.name = name; this.salary = salary; } //Getters & Setters } |
Standard Comparator
1 2 3 4 5 6 |
Comparator<Employee> sortByName = new Comparator<Employee>() { @Override public int compare(Employee e1, Employee e2) { return e1.getName().compareTo(e2.getName()); } }; |
Lambda Equivalent
1 2 |
Comparator<Employee> lambdaSortByName = (Employee e1, Employee e2) -> e1.getName().compareTo(e2.getName()); |
Sorting
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// Initial data ArrayList<Employee> list = new ArrayList<Employee>(); list.add(new Employee(500, "Shifoo", 150000)); list.add(new Employee(504, "Oogway", 120000)); list.add(new Employee(503, "Tigress", 100000)); list.add(new Employee(730, "Mantis", 45000)); System.out.println("Initial List :"); list.forEach(System.out::println); //sortByName already defined in above snippet Collections.sort(list, sortByName); System.out.println("\nStandard Sorted by Name :"); list.forEach(System.out::println); //lambdaSortByName already defined in above snippet list.sort(lambdaSortByName); System.out.println("\nLambda Sorted by Name :"); list.forEach(System.out::println); Comparator<Employee> lambdaSortById = (Employee e1, Employee e2) -> e1.getId() - e2.getId(); list.sort(lambdaSortById); System.out.println("\nSorted by Id :"); list.forEach(System.out::println); |
Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Initial List : 500, Shifoo, 150000.0 504, Oogway, 120000.0 503, Tigress, 100000.0 730, Mantis, 45000.0 Standard Sorted by Name : 730, Mantis, 45000.0 504, Oogway, 120000.0 500, Shifoo, 150000.0 503, Tigress, 100000.0 Lambda Sorted by Name : 730, Mantis, 45000.0 504, Oogway, 120000.0 500, Shifoo, 150000.0 503, Tigress, 100000.0 Sorted by Id : 500, Shifoo, 150000.0 503, Tigress, 100000.0 504, Oogway, 120000.0 730, Mantis, 45000.0 |
You can also see adding different comparison criteria is easy and compact. The above example also points out other improvements added in Java 8. But we will discuss them later in the article.
Default Methods
From Java 8 onwards your interfaces can have method implementations as well. These implementations are defined with keyword default. The class implementing the interface can access these methods or they can even override the default methods.
We will define sample interfaces for Printer and Scanner.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public class DefaultMethodsTest { public static void main(String args[]) { Printer printer = new PrinterAndScanner(); printer.print(); } } interface Printer { default void print() { System.out.println("I can print!"); } } interface Scanner { default void scan() { System.out.println("I can scan!"); } } class PrinterAndScanner implements Printer, Scanner { public void print() { Scanner.super.scan(); Printer.super.print(); } } |
In above, we see that class PrinterAndScanner scans and prints. Thus it combines the functionality of two different types of machines.
The default methods will not break any old instances of the interface.
Date and Time API
Java 8 comes with a new date-time API under the package java.time. The new API is thread safe. Out of whole new classes under this new API, you may want to know few first like LocalDate, LocalTime, LocalDateTime, DateTimeFormatter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Current Date LocalDate today = LocalDate.now(); System.out.println("Current Date = " + today); LocalDate todayNewYork = LocalDate.now(ZoneId.of("America/New_York")); System.out.println("Current Date in America = " + todayNewYork); // Current Time LocalTime time = LocalTime.now(); System.out.println("Current Time = " + time); LocalTime timeNewYork = LocalTime.now(ZoneId.of("America/New_York")); System.out.println("Current Time in America = " + timeNewYork); // Current Date LocalDateTime now = LocalDateTime.now(); System.out.println("Current DateTime = " + now); System.out.println(now.format(DateTimeFormatter.ofPattern("dd/MM/YYYY HH:mm:ss"))); |
Output
1 2 3 4 5 6 |
Current Date = 2018-02-17 Current Date in America = 2018-02-16 Current Time = 01:58:34.463 Current Time in America = 15:28:34.464 Current DateTime = 2018-02-17T01:58:34.464 17/02/2018 01:58:34 |
Streams
This is one of the major new features in Java 8. A new package java.util.stream with new functionality which contains classes for processing sequences of elements.
Streams can be created using List, Arrays
1 2 3 4 5 6 7 8 9 10 11 |
String[] arr = new String[]{"P", "A", "V"}; Stream<String> stream = Arrays.stream(arr); stream.forEach(System.out::println); stream = Stream.of("V", "A", "P"); stream.forEach(System.out::println); List<String> list = Arrays.asList("Pavan", "Opencodez"); stream = list.stream(); list.parallelStream().forEach(System.out::println); |
The above code snippet also takes you through one of the interesting feature added in Java 8, Parallel Operation. The parallelStream() method makes sure the elements of a list are handled parallelly, thus improving performance.
Apart from above, Streams comes with vast add-on functionality that will make your life easier if used carefully.
Iterating
1 |
stream.forEach(System.out::println); |
Filtering
1 |
list.stream().filter(element -> element.contains("P")); |
Matching
1 |
boolean isValid = list.stream().anyMatch(element -> element.contains("P")); |
Collecting
1 2 |
List<String> results = list.stream().map(element -> element.toUpperCase()).collect(Collectors.toList()); |
Read here In-Depth Tutorial on Streams
forEach() Method
As we have already seen default methods above, forEach is default method added to improved Java8 interface Iterable
Iterating over List
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ArrayList<Employee> list = new ArrayList<Employee>(); list.add(new Employee(500, "Shifoo", 150000)); list.add(new Employee(504, "Oogway", 120000)); list.add(new Employee(503, "Tigress", 100000)); list.add(new Employee(730, "Mantis", 45000)); System.out.println("Printing List with forEach"); list.forEach(employee -> System.out.println(employee)); System.out.println("\nPrinting List after Filtering"); list.stream() .filter(employee -> employee.getSalary() > 100000) .forEach(System.out::println); |
Output
1 2 3 4 5 6 7 8 9 |
Printing List with forEach 500, Shifoo, 150000.0 504, Oogway, 120000.0 503, Tigress, 100000.0 730, Mantis, 45000.0 Printing List after Filtering 500, Shifoo, 150000.0 504, Oogway, 120000.0 |
Iterating over Map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Map<Integer, Employee> items = new HashMap<>(); items.put(500,new Employee(500, "Shifoo", 150000)); items.put(504, new Employee(504, "Oogway", 120000)); items.put(503, new Employee(503, "Tigress", 100000)); items.put(730, new Employee(730, "Mantis", 45000)); System.out.println("Printing Map with forEach"); items.forEach((k,v)->System.out.println("Key : " + k + " Value : " + v)); System.out.println("\nPrinting Map with forEach"); items.forEach((k,v)->{ System.out.println("Key : " + k + " Value : " + v); if("Oogway".equals(v.getName())){ System.out.println("Hello Master " + v.getName()); } }); |
Output
1 2 3 4 5 6 7 8 9 10 11 12 |
Printing Map with forEach Key : 500 Value : 500, Shifoo, 150000.0 Key : 503 Value : 503, Tigress, 100000.0 Key : 504 Value : 504, Oogway, 120000.0 Key : 730 Value : 730, Mantis, 45000.0 Printing Map with forEach Key : 500 Value : 500, Shifoo, 150000.0 Key : 503 Value : 503, Tigress, 100000.0 Key : 504 Value : 504, Oogway, 120000.0 Hello Master Oogway Key : 730 Value : 730, Mantis, 45000.0 |
Type Annotations
With Type Annotations you can apply an annotation anywhere a type is used, not just on a declaration. Type Annotations adds stronger type checking to your Java code. Below are few annotations:
@NonNull – The compiler can determine code path that may receive a null value.
@ReadOnly – The compiler will raise a flat if any attempt to change the object.
@Regex – With this annotation, compiler checks if given string is valid regular expression or not.
Repeating Annotations
Repeating Annotations provide the ability to apply the same annotation type more than once to the same declaration or type use. E.g. is if you want to schedule a taks with multiple triggers you will implement a repeating annotation and use:
1 2 3 |
@Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23") public void scheduledTask() { ... } |
When we develop a repeating annotation we need to annotate it with @Repeatable meta-annotation.
1 2 3 4 5 6 |
@Repeatable(Schedules.class) public @interface Schedule { String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default 12; } |
To maintain the backward compatibility, these annotations are implemented along with containing annotation. We will provide a Containing Annotation as:
1 2 3 |
public @interface Schedules { Schedule[] value(); } |
You can retrieve the annotations with help of several methods available in the Reflection API. One such method is:
1 2 3 4 |
Schedule[] schedules = <YourClass>.class.getAnnotationsByType(Schedule.class); for (Schedule schedule : schedules) { System.out.println(schedule.dayOfMonth()); } |
Conclusion
In this article, we tried to learn Java 8 using examples. The code snippets are easy and straightforward. Please feel free to comment or ask a question or two.
Great article! I want to start career in java programming and so was looking for ‘what makes java different from other languages in features’. Here found your article very interesting and helpful as java beginner. Thanks a lot for sharing java 8 features with us!