Java 9 Improvements-1

Table of contents
Reading Time: 3 minutes

There are a couple of improvements in Java 9. We will cover it one by one with the examples of each.

1.) Interface private methods: In Java 9, we can create private methods in interfaces. The use case is very simple: similar to classes where you put the repetitive code in a private method and reuse that in other methods, you can simply create one private helper method in the interface as well, that can be used by other default methods, which helps us to prevent writing boilerplate code.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


interface Util {
default int numberOfStudents() {
return helper();
}
private int helper() {
return 10;
}
static int getCores() {
return helper1();
}
private static int helper1() {
return 2;
}
}
public class Sample {
public static void main(String[] args) {
System.out.println("OK");
}
}
view raw

sample.java

hosted with ❤ by GitHub


2.) No _(underscore): In Java 9, underscore is a keyword. As such you can’t use this as a variable name as you can in Java8. Even in Java8, using this as a variable name generates a warning but in Java9 it throws an error. So, the _(underscore ) is no more used as an identifier.

Now, the question is why did they do that?
The answer is very simple: to give a meaningful and appropriate name to the variable.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


public class Sample {
public static void main(String[] args) {
int _ = 4;
System.out.println(_);
}
}
view raw

sample1.java

hosted with ❤ by GitHub

This will throw a compile time error:  As of release 9, ‘_’ is a keyword, and may not be used as an identifier.

3.) takeWhile: In Java 9, we have a method takeWhile that is similar to limit() in Java 8  with the only difference, that is:
limit() is based on the count value that we are passing to it as a parameter. Let’s take an example.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


public class Limit {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(11,22,33,44,55,66,77,88,99);
numbers.stream()
.limit(4)
.forEach(System.out::println);
}
}
view raw

limit.java

hosted with ❤ by GitHub

In the above example, I said the limit is so it will only allow me to pass 4 values.
i.e: 11, 22, 33, 44

Now, let’s take a scenario: what if I want to use limit, not on a fixed number but I want a limit based on a condition?

takeWhile(predicate) is the solution to this problem. It will close the gate as soon as the predicate is false. Let’s go through this with one example:



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


public class Sample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(11, 22, 33, 44, 55, 66, 77, 88, 99);
numbers.stream()
.takeWhile(e -> e < 66)
.forEach(System.out::println);
}
}
view raw

takewhile.java

hosted with ❤ by GitHub

4.) dropWhile: In Java 9, we have a method dropWhile() that is similar to skip() in Java 8  with the only difference, that is:
skip(count) is based on the count value that we are passing to it as a parameter. Let’s take an example.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


public class SkipExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(11, 22, 33, 44, 55, 66, 77, 88, 99);
numbers.stream()
.skip(5)
.forEach(System.out::println);
}
}

In the above example, it will skip the first five values and it will start printing from the 6th value. Same as earlier situation, what if I want to use skip(count) on condition basis, then dropWhile(predicate)  is the solution. Let’s go through this with one example:



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


public class DropWhileExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(11, 22, 33, 44, 55, 66, 77, 88, 99);
numbers.stream()
.dropWhile(e -> e < 55)
.forEach(System.out::println);
}
}

5.) IntStream iterate: In Java 8 we have an alternative to for-loop i.e.

IntStream.range(0, 5)
        .forEach(System.out::println);

The above statement does same work as below for-loop.

for(int i=0; i<5; i++){
    System.out.println(i);
}

Let’s take one scenario where I want to increment the counter value in for-loop by 2 each time as below:

for(int i=0; i<5; i = i+2){
    System.out.println(i);
}

In Java 8, this is not really easy to do. Java 9 overcame this kind of situation as below:



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


public class IntStreamIterateExample {
public static void main(String[] args) {
IntStream.iterate(0, i -> i<5, i -> i+2 )
.forEach(System.out::println);
}
}

In the above example, we can see how we can write code in a functional way to solve this kind of problem. It’s good to know what type of arguments iterate() method takes.

IntStream.iterate(seed, predicate, function)

The first argument is the seed value and the second argument is the predicate and the last argument is a function.

6.) Improved Optional:  In Java8, there were some problems with Optional that we will cover with the below example.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


public class IfPresentOrElseExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80, 90);
Optional<Integer> first = numbers.stream().filter(a -> a > 500).findFirst();
if (first.isPresent()) {
System.out.println(first.get());
} else {
System.out.println("Value not found");
}
}
}

In the above example, there is one limitation, that is, we are writing code in an imperative pattern instead of the functional pattern because we are following best practices instead of using get() on optional. This is the limitation in Java 8.

Now, we will see the example how Java 9 overcomes this problem.



This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters


public class IfPresentExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80, 90);
Optional<Integer> first = numbers.stream().filter(a -> a > 500).findFirst();
first.ifPresentOrElse( a-> System.out.println(a), () -> System.out.println(""));
}
}

These were just the basic yet powerful new features of Java 9. We will come up with more advanced features such as Jlink and modularity in the next series of this blog.

References: https://www.youtube.com/watch?v=Yacu1yUktjY&t=3498s

knoldus-advt-sticker

Written by 

Kunal Sethi is a Software Consultant with experience of more than 2.5 years. He is a Java enthusiast and has knowledge of various programming languages such as Scala, C++. He is familiar with Object-Oriented Programming Paradigms, loves to code applications in J2EE. He developed his own stand-alone application in Java based on the intranet chatting System and email system during his Master's Degree.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading