Friday, 4 November 2016

How to compare String by their length in Java 7 and 8?

The natural way to compare String is the lexicographic way, which is implemented in the compareTo() method of String class, but sometimes you need to compare String by their length. You cannot use the default compareTo() method for that task, you need to write your own custom Comparator, which can compare String by length. Don't worry, It's easy to compare multiple String by their length, all you need to write is a Comparator which calculates their length using the length() method and compare them. Such comparator should return a positive value if first String has a length greater than second String, a negative value if the length of first String is less than the length of second String and zero if both String has the same length.

You can define such one-off Comparator by using Anonymous inner class as shown in this article and further use it to sort a list of String on their length. This is a very useful technique and works fine in Java 6 and 7 but works fantastically well in Java 8 due to less clutter provided by the brand new feature called lambda expressions.

Here is how you can do it pre Java 8 world :

public int compare(String s1, String s2) {
    return s1.length() - s2.length();
}

In Java 8 world, it's even simpler by using lambda expression and new default methods added on java.util.Comparator class as shown below :

Comparator<String> strlenComp = (a, b) -> Integer.compare(a.length(), b.length());

Here are a and b are two String object. This Integer.compare() is a new method added to Java 8. Since we are using Comparator of String, the compiler is also smart enough to infer the types of a and b, which is, of course, String.

How to sort List of String by their length in Java 7 and 8

Here is an example of using this String length comparator to sort a list of String by their length.  In this program, we have demonstrated both JDK 6 and 7 way by using Anonymous class and new Java 8 way by using lambda expressions. You can see that the Java 8 way takes just one line and it's a lot easier to understand once you get familiar with the syntax of lambda expressions.

Java 6, 7

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/*
 * Java Program to sort list of String by their length
 */

public class StringComparisonByLength{

  public static void main(String[] args) {

    List<String> books = new ArrayList<>(Arrays.asList("Effective Java",
                                   "Algorithms", "Refactoring" ));
    System.out.println("Sorting List of String by length in JDK 7 ======");
    System.out.println("The original list without sorting");
    System.out.println(books);
   
    Comparator<String> byLength = new Comparator<String>(){
      @Override
      public int compare(String s1, String s2) {
        return s1.length() - s2.length();
        }
    };
   
    Collections.sort(books, byLength);
    System.out.println("The same list after sorting string by length");
    System.out.println(books);
  }
}

Output
Sorting List of String by length in JDK 7 ======
The original list without sorting
[Effective Java, Algorithms, Refactoring]
The same list after sorting string by length
[Algorithms, Refactoring, Effective Java]


Java 8

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/*
 * Java Program to sort list of String by their length in JDK 8
 */

public class SortingListOfStringByLength{

  public static void main(String[] args) {  
   
    // In Java 8
    System.out.println("Sorting List of String by length in Java 8 ======");
    List<String> cities = new ArrayList<>(Arrays.asList("London", "Tokyo", "NewYork"));
    System.out.println("The original list without sorting");
    System.out.println(cities);

    cities.sort((first, second) -> Integer.compare(first.length(), second.length()));
   
    System.out.println("The same list after sorting string by length");
    System.out.println(cities);
  }
}

Output
Sorting List of String by length in Java 8 ======
The original list without sorting
[London, Tokyo, NewYork]
The same list after sorting string by length
[Tokyo, London, NewYork]

That's all about how to compare String by their length and how you can sort a list of String by their length in Java 7 and Java 8. You can see it lot more convenient in Java 8 as you can create custom Comparator in just one line by using the lambda expression. The JDK 8 API is full of such methods to faciliate even more complex comparison e.g.  by using thenComparing() method you can chain multiple comparators.