New Features in Java 9: Private Methods in Interfaces

September 21, 2017

Java 9 is out!

Java 9 came out today, so it is time to see what it brought to us. As a gentle start, let’s take a look at private methods in interfaces.

What is the use of private methods in interfaces?

Since Java 8 it is possible to have actual implementation in interfaces with the help of default methods, but without private methods, it was impossible to share common implementation parts between two or more default methods without making the common parts visible or by copy-pasting the common parts into all places where it was needed.

Example

Let’s take a similar task as in the Autoboxing and Streams post: we want to filter out even or odd numbers from a list of integers. We have seen that depending on the amount of elements it is sometimes worth doing it in a parallel way and sometimes it doesn’t: when there are not too many elements in the list, a serial stream could be even faster, since the overhead of the fork/join framework and threads is bigger then the actual gain of performing the task parallel.
Let’s say we made measurements and if there are 300,000 elements, the hardware we have benefits from parallel streams. With the help of private methods we can offer all users of our interface with the methods of removeEvenNumbers and removeOddNumbers where we hide the complexity of choosing between parallel and serial processing and we eliminate code duplication as well:

import java.util.List;
import java.util.function.IntPredicate;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

public interface NumberRemover {
  //---DEFAULT METHODS---

  default List<Integer> removeEvenNumbers(List<Integer> list){
    return remove(list.size() > 300_000 ? list.parallelStream() : list.stream(), i -> i % 2 != 0);
  }

  default List<Integer> removeOddNumbers(List<Integer> list){
    return remove(list.size() > 300_000 ? list.parallelStream() : list.stream(), i -> i % 2 == 0);
  }

  //---PRIVATE METHODS---

  private List<Integer> remove(Stream<Integer> stream, IntPredicate filterPredicate){
    return stream.mapToInt(n -> n).filter(filterPredicate).sorted().boxed().collect(toList());
  }
}

The removeEvenNumbers and removeOddNumbers methods check the number of elements and decide if the removal should be done with a serial or parallel stream. The filtering is done with the help of the remove method which takes two parameters: an either serial or parallel stream and an IntPredicate which represents the actual filtering which needs to be done (to avoid autoboxing we are not using Predicate<Integer>).
Any class which implements the NumberRemover interface will have access to the two default methods while the private method is hidden from them.

Conclusion

Having private methods in Java 9 interfaces might be an overlooked or under appreciated improvement of the language, but using private methods in interfaces could help making implementation in interfaces more concise.

András Döbröntey

About the Author

András Döbröntey

Leave a Comment:

Bitnami