JB Header
Java 8 - List.sort, List.replaceAll methods tutorial with examples
This is the 3rd article, of a 4 part article series, covering the important enhancements which have been introduced in Collections API in Java 8. While the 1st part of the series explained the enhancements introduced in Iterable and Iterator interfaces in Java 8(read 1st partRead Part 1-Iterable.forEach,Iterator.remove methods tutorial), the 2nd part covered Collection interface's new default method removeIf()(read 2nd partRead Part 2-Collection.removeIf method tutorial).

In this part 3 of 4, I will be looking at java.util.List interface and will explain the new default methods which have been introduced in the interface in Java 8 viz. List.sort() and List.replaceAll(). We will understand the working of these two methods along with seeing examples showing their usage. New default method replaceAll() added to the List Interface in Java 8 The new default method List.replaceAll() has been written for scenarios where a particular action has to be performed on all the elements of a list. List.replaceAll() is thus a bulk mutation operation.

An important point to note regarding replaceAll() method is that it does NOT change the type of the elements in the list. So, a list of say Strings will continue to contain Strings but using replaceAll() you can apply some common function on all the Strings in the list. An example of a replaceAll() call on a list of Strings would be to CAPITALIZE all Strings and the like.

Let us now take a look at the signature of the List.replaceAll() method -
default void replaceAll(UnaryOperator<E> operator)
Where,
     - operator is the only parameter and is an instance of a UnaryOperator Functional Interface.
idea icon What is a UnaryOperator
java.util.function.UnaryOperator is a functional interface, and is a specialization of FunctionClick to read detailed tutorial on Java 8's Function Interface with the operand and the return value being of the same type. I.e. UnaryOperator<E> takes a single input of type E, and returns an output of the same type E.
Let us now see an example of using List.replaceAll() to do a specific action on all elements of a List. In the below code snippet, each of the 5 employees of some company are being given a salary hike of 10% across the board using List.replaceAll() method.
Java 8 code to do a specific change on all elements of a List using List.replaceAll()
package com.javabrahman.java8;
public class Employee {
  private String name;
  private Integer age;
  private Double salary;
  public Employee(String name, Integer age, Double salary) {
    this.name = name;
    this.age = age;
    this.salary = salary;
  }
  public String toString(){
    DecimalFormat dformat = new DecimalFormat(".##");
    return "Employee Name:"+this.name
        +"  Age:"+this.age
        +"  Salary:"+dformat.format(this.salary);
  }
//getters and setters for name, age and salary go here
//standard equals() and hashcode() code go here
}
//ListReplaceAllExample.java
package com.javabrahman.java8.collections;
import com.javabrahman.java8.Employee;
import java.util.Arrays;
import java.util.List;
public class ListReplaceAllExample {
  static List<Employee> employeeList = Arrays.asList(
      new Employee("Tom Jones", 45, 7000.00),
      new Employee("Harry Major", 25, 10000.00),
      new Employee("Ethan Hardy", 65, 8000.00),
      new Employee("Nancy Smith", 22, 12000.00),
      new Employee("Deborah Sprightly", 29, 9000.00));
  public static void main(String[] args) {
    employeeList.replaceAll(employee -> {
      employee.setSalary(employee.getSalary() * 1.1);
      return employee;
    });
    System.out.println("Employee list with all salaries incremented by 10%");
    employeeList.forEach(System.out::println);
  }
}
 OUTPUT of the above code
Employee list with all salaries incremented by 10%
Employee Name: Tom Jones    Age:45    Salary:7700.0
Employee Name: Harry Major    Age:25    Salary:11000.0
Employee Name: Ethan Hardy    Age:65    Salary:8800.0
Employee Name: Nancy Smith    Age:22    Salary:13200.0
Employee Name: Deborah Sprightly    Age:29    Salary:9900.0
Explanation of the code
  • Employee class has 3 main attributes - name, age and salary.
  • We create a List of Employee objects, named employeeList, and add 5 Employee objects to it.
  • replaceAll() method is invoked on the employeeList with the input being a lambda expressionRead Java 8 Lambda Expressions Tutorial equivalent to a UnaryOperator function - (employee -> {employee.setSalary(employee.getSalary() * 1.1);return employee;});
  • This lambda expression takes an employee as input and sets the salary of the employee at a value which is 10% more than the employee's current salary.
  • Lastly, the List of employees is printed. The salaries of all the employees has been increased by 10% as expected.
New default method sort() added to the List Interface in Java 8 List.sort() is a new default method introduced in Java 8 which sorts the given list based on the Comparator instance passed to it as input. Let us start understanding the method by first looking at its signature -
default void sort(Comparator<? super E> c)
Where,
     - c is the only parameter and is an instance of a ComparatorClick to read detailed tutorial on Java 8 Comparators which is an ancestor of type E, where E is the type of the elements in the List being sorted.

Why create a new method List.sort() when Collections.sort() was already there Prior to Java 8, Collections.sort() method was popularly used to lists. However, there was a drawback with Collections.sort() that it doesn't sort in-place. An in-place sort saves both on memory (by not requiring space other than that occupied by its elements) and time ( as the twin tasks of creating a temporary copy of the list to be sorted and then copying the sorted elements back into the original list are no longer required).

List.sort(), however, does use an in-place variant of merge sort to sort the List elements. As a result it provides both the space and time benefits mentioned above. In fact, in Java 8, the Collections.sort() method itself internally calls List.sort() to sort the List elements.

Let us now take a look an example showing List.sort() usage. We will use the same list of employees as we used in the previous code snippet and sort them in the order of increasing order of their salary.
(Note – I am leaving out the code for Employee class below as it is the same as used in the replaceAll() code above.)
Java 8 code to sort a List using List.sort() default method
package com.javabrahman.java8.collections;
import com.javabrahman.java8.Employee;
import java.util.Arrays;
import java.util.List;
public class ListSortExample {
  static List<Employee> employeeList = Arrays.asList(
      new Employee("Tom Jones", 45, 7000.00),
      new Employee("Harry Major", 25, 10000.00),
      new Employee("Ethan Hardy", 65, 8000.00),
      new Employee("Nancy Smith", 22, 12000.00),
      new Employee("Deborah Sprightly", 29, 9000.00));
  public static void main(String[] args) {
    employeeList.sort((emp1, emp2)-> 
                      Double.compare(emp1.getSalary(),emp2.getSalary()));
    System.out.println("Employee list sorted by their salaries");
    employeeList.forEach(System.out::println);
  }
}
 OUTPUT of the above code
Employee list sorted by their salaries
Employee Name: Tom Jones    Age:45    Salary:7000.0
Employee Name: Ethan Hardy    Age:65    Salary:8000.0
Employee Name: Deborah Sprightly    Age:29    Salary:9000.0
Employee Name: Harry Major    Age:25    Salary:10000.0
Employee Name: Nancy Smith    Age:22    Salary:12000.0
Explanation of the code
  • A list of 5 Employee objects is created, named employeeList.
  • sort() method is invoked on employeeList with the lambda expression equivalent of a Double Comparator being passed to it - (emp1, emp2)-> Double.compare( emp1.getSalary(),emp2.getSalary() ) .
  • Definition of Double.compare() method matches the function descriptorRead tutorial on Java 8 Function Descriptors of Comparator interface, allowing us to use the above lambda expression.
  • The sorted employeeList's Employee objects are then printed. As expected the Employee objects have been sorted in the increasing order of their salary.
Conclusion In this 3rd part of the 4-part Java 8 Collection Enhancements Series, we looked at the new default methods List.replaceAll() and List.sort() introduced in Java 8. We understood the working of these new methods and also saw examples showing their usage.

In the next(and ultimate) article of the series, we will be looking at the Java 8's new Collection API enhancements introduced in Map interface which ease the effort required to handle multi-value maps aka multimaps.