Functional Interface Explained in Detail Introduced From Java 8

Originally published August 2020

Functional interfaces are introduced as part of Java 8. It is implemented using the annotation called @FunctionalInterface. It ensures that the interface should have only one abstract method. The usage of the abstract keyword is optional as the method defined inside the interface is by default abstract. It is important to note that a functional interface can have multiple default methods (it can be said concrete methods which are default), but only one abstract method. The default method has been introduced in interface so that a new method can be appended in the class without affecting the implementing class of the existing interfaces. Prior to Java 8, the implementing class of an interface had to implement all the abstract methods defined in the interface.

Functional Programming Patterns With Java 8

It’s been four years since functional programming became feasible in Java. The means we have had four years to play with Java 8.

And we've played... and played. After developing several large enterprise projects that made heavy use of Lambdas and Streams, consulted many other projects in doing so, and taught these concepts to hundreds of developers as an independent trainer, I think it’s time to summarize patterns, best practices, and anti-patterns.

Lambdas for Concurrent Maps

The package java.util.concurrent contains two concurrent maps, the class ConcurrentHashMap, and the class ConcurrentSkipListMap. Both classes are thread-safe and high performant. But using them is error-prone because of reading modify write race conditions. Here come lambda expressions into the play. Lambda expressions help us to avoid these race conditions elegantly.

Let us see how.

Java 8 Comparator: How to Sort a List

In this article, we’re going to see several examples on how to sort a List in Java 8.

Sort a List of Strings Alphabetically

List<String> cities = Arrays.asList(
       "Milan",
       "london",
       "San Francisco",
       "Tokyo",
       "New Delhi"
);
System.out.println(cities);
//[Milan, london, San Francisco, Tokyo, New Delhi]

cities.sort(String.CASE_INSENSITIVE_ORDER);
System.out.println(cities);
//[london, Milan, New Delhi, San Francisco, Tokyo]

cities.sort(Comparator.naturalOrder());
System.out.println(cities);
//[Milan, New Delhi, San Francisco, Tokyo, london]

We’ve written London with a lowercase "L" to better highlight differences between Comparator.naturalOrder(), which returns a Comparator that sorts by placing capital letters first, and String.CASE_INSENSITIVE_ORDER, which returns a case-insensitive Comparator.