Writing Readable Code With Java 8 Method References

Sitewide-10usd300x250 Java 8 lambda expressions make our code concise and readable. However, it’s the method references, along with the static and default methods in functional interfaces, which makes our code shine.

Let’s take an example. Suppose we have an array of names that we want to sort. The array looks like this:

String[] names = {"Mr Sanjay", "Ms Trupti", "Dr John"};

Notice that the names are prefixed with title. Now, to sort these by first name using Java 7, you may code something as below:

Arrays.sort(names, new Comparator<String>(){

	@Override
	public int compare(String name1, String name2) {
		
		return name1.split(" ")[1].compareTo(name2.split(" ")[1]);
	}
});

name.split(" ")[1] would extract the first name from the string.

But, we are in Java 8 era, and so would use a lambda expression, as below:

Arrays.sort(names, (name1, name2)  -> name1.split(" ")[1].compareTo(name2.split(" ")[1]));

Hold on! The Comparator interface now has a static comparing method, which, given the field to compare, returns a comparator object (or lambda expression, whatever you name it). Using that, our code now becomes:

Arrays.sort(names, comparing(name  -> name.split(" ")[1]));

name -> name.split(" ")[1] is the lambda expression for extracting the first name. Now, if we have somewhere a static method to extract the first name, our code would be much more readable. For example, say we have a Name class as below:

class Name {

    public static String title(String name) {

        return name1.split(" ")[0];
    }

    public static String first(String name) {

        return name1.split(" ")[1];
    }
}

It just has a couple of static methods, for returning the title and first name from a name.

Now, using method reference, our comparing code becomes:

Arrays.sort(names, comparing(Name::first));

See how readable it is! Just looks like plain English – comparing by first name.

What if you want to compare in reverse order? The Comparator interface provides a default reversed method that returns another comparator which it the opposite of the given one. We’ll simply call that:

Arrays.sort(names, comparing(Name::first).reversed());

Next, suppose we need to compare by title if the first names are equal. How to go about that?

The Comparator interface also provides a default thenComparing method, which returns another comparator with another condition topped up. We can use that:

Arrays.sort(names, comparing(Name::first).reversed().thenComparing(Name::title));

Let’s read it – “comparing by first name reversed, and then by title.” Wow!

Note: This example is picked from my new video tutorial Java 8 Functional Programming: Lambda Expressions Quickly.

Leave a Reply

Your email address will not be published. Required fields are marked *