dreamsys software

Java 8 Lambda Expressions Tutorial

Comparator

Now let's look at how we do comparators in Java for things like sorting. First we are going to create a simple User class which we will use in this and several other parts of the tutorial.

public class User {
  Integer id;
  String firstName;
  String lastName;
  Integer age;

  User() {}
  User(int id, String first, String last, int age) {
    this.id = id;
    this.firstName = first;
    this.lastName = last;
    this.age = age;
  }

  public String toString() {
    return "" + id + ", " + firstName + ", " + lastName + ", " + age;
  }
}

Normally in java you will create getters and setters and make your members private, but for the sake of brevity we will just use package level scope on these java fields. We have a simple constructor and a toString() method to make it easier to read the values printed out.

Now let's create a class which prints out a list of users sorted by each of the fields. First we will do it the old way and then the new way.

import java.util.*;

public class UserTest {
  private static List<User> users = Arrays.asList(
      new User(1, "Steve", "Vai", 40),
      new User(4, "Joe", "Smith", 32),
      new User(3, "Steve", "Johnson", 57),
      new User(9, "Mike", "Stevens", 18),
      new User(10, "George", "Armstrong", 24),
      new User(2, "Jim", "Smith", 40),
      new User(8, "Chuck", "Schneider", 34),
      new User(5, "Jorje", "Gonzales", 22),
      new User(6, "Jane", "Michaels", 47),
      new User(7, "Kim", "Berlie", 60)
    );

  public static void main(String[] args) {
    oldJavaWay();
    newJavaWay();
  }

  private static void oldJavaWay() {
    Collections.sort(users, new Comparator<User>() {
      public int compare(User u1, User u2) {
        return u1.id.compareTo(u2.id);
      }
    });

    printListOldWay("by ID");

    Collections.sort(users, new Comparator<User>() {
      public int compare(User u1, User u2) {
        return u1.firstName.compareTo(u2.firstName);
      }
    });

    printListOldWay("by FirstName");

    Collections.sort(users, new Comparator<User>() {
      public int compare(User u1, User u2) {
        return u1.lastName.compareTo(u2.lastName);
      }
    });

    printListOldWay("by LastName");

    Collections.sort(users, new Comparator<User>() {
      public int compare(User u1, User u2) {
        return u1.age.compareTo(u2.age);
      }
    });

    printListOldWay("by Age");
  }

  private static void printListOldWay(String type) {
    System.out.println("Old Way " + type + ":");

    for (User u : users) {
      System.out.println("\t" + u);
    }

    System.out.println();
  }

  private static void newJavaWay() {
    Collections.sort(users, (User u1, User u2) -> u1.id.compareTo(u2.id));
    printListNewWay("by ID");

    Collections.sort(users, (User u1, User u2) -> u1.firstName.compareTo(u2.firstName));
    printListNewWay("by FirstName");

    Collections.sort(users, (User u1, User u2) -> u1.lastName.compareTo(u2.lastName));
    printListNewWay("by LastName");

    Collections.sort(users, (User u1, User u2) -> u1.age.compareTo(u2.age));
    printListNewWay("by Age");

  }

  private static void printListNewWay(String type) {
    System.out.println("New Way " + type + ":");

    users.forEach(u -> System.out.println("\t" + u));

    System.out.println();
  }
}

If you run this class, it will print out the list of users sorted first by ID, then by FirstName, lastName and finally by Age. It will do this once the old way and then the new way. Let's take a look at how things are done the old way first:

  Collections.sort(users, new Comparator<User>() {
    public int compare(User u1, User u2) {
      return u1.id.compareTo(u2.id);
    }
  });

We make a call to Collections.sort and give it our User list and then a comparator implementation. This implementation will contain one method, compare that will return the results of the specified field calling compareTo from one object to the other. After we do this, we then call the print method the old way:

for (User u : users) {
  System.out.println("\t" + u);
}

We do the familiar for loop to loop through each User object and then print it to the console.

Now let's take a look at how we do this using lambda expressions.

Collections.sort(users, (User u1, User u2) -> u1.id.compareTo(u2.id));

The call to Collections.sort has been moved into one single line. We create an anonymous function that takes two User objects then the contents of that function just return the same compareTo method call. The printing of the user list is also done as a single line now:

users.forEach(u -> System.out.println("\t" + u));

We use the forEach method on the Collection and give it an anonymous function which has a parameter u and the contents simply print the u object to the console. Notice that we don't have to specify that u is type User, the compiler is smart enough to figure this out if necessary, otherwise it will simply use Object.

In the next section, we will take a look at how we can filter collections.


Prev (Introduction) | Next (Filter)


Blog Entries
Blob Entry 1
Blob Entry 2
Blob Entry 3
Blob Entry 4
Blob Entry 5
Blob Entry 6