In this article, we will discuss how to sort list of Objects on the basis of specific double parameter/field using Java 8 Comparator’s static method comparingDouble() which accepts ToDoubleFunction functional interface
1. Comparator.comparingDouble() method :
- This static method accepts a function that extracts a double sort key from a type T
- Returns a Comparator that compares by that sort key
- The returned comparator is serializable if the specified function is also serializable
- Method signature :-
- static <T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor)
- Where
- T is the type of element to be compared
- keyExtractor is the function used to extract the double sort key
- Exception :- Throws NullPointerException, if the argument is null
2. Comparator.comparingDouble() examples :
2.1 Sort Product list according to their Price
- Product class is defined with 4 attributes namely id, name, quantity and their price
- Along with 4 attributes, parameterized constructor, getters/setters and toString() method is defined – removed for brevity
- Member variable price is of type primitive double
Product.java
package net.bench.resources.comparator.comparingdouble;
public class Product {
// member variables
private int id;
private String name;
private long quantity;
private double price;
// 4-arg parameterized constructor
// getters and setters
// toString() method
}
SortProductListByPrice.java
- A list contains Product information for 5 as per insertion-order
- Sorting :- we are going to sort the Product list in the increasing order of Price using Stream‘s sorted() method passing Comparator.comparingDouble() as argument
- Comparator.comparingDouble() accepts ToDoubleFunction which means it accepts key of double type only
package net.bench.resources.comparator.comparingdouble;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class SortProductListByPrice {
// List of Products
private static List<Product> getProductList() {
return Arrays.asList(
new Product(102, "Rice", 502L, 58.19),
new Product(104, "Oil", 208L, 164.75),
new Product(103, "Lentils", 803L, 102.45),
new Product(105, "Vegetables", 303L, 45.50),
new Product(101, "Wheat", 1089L, 36.89)
);
}
public static void main(String[] args) {
// 1. get Product list
List<Product> products = getProductList();
// 1.1 print to console
System.out.println("Product list as per Insertion-order :-\n");
products.forEach(System.out::println); // iterating/printing
// 2. sorting Product list in increasing-order of their Price
System.out.println("\n\nSorted Product list"
+ " in increasing-order of Price :-\n");
// 2.1 sorting/iterating/printing
products
.stream() // 1. get sequential stream
.sorted(Comparator.comparingDouble(Product::getPrice)) // 2. double sorting
.forEach(System.out::println); // 3. iterate/printing
}
}
Output:
Product list as per Insertion-order :-
Product [id=102, name=Rice, quantity=502, price=58.19]
Product [id=104, name=Oil, quantity=208, price=164.75]
Product [id=103, name=Lentils, quantity=803, price=102.45]
Product [id=105, name=Vegetables, quantity=303, price=45.5]
Product [id=101, name=Wheat, quantity=1089, price=36.89]
Sorted Product list in increasing-order of Price :-
Product [id=101, name=Wheat, quantity=1089, price=36.89]
Product [id=105, name=Vegetables, quantity=303, price=45.5]
Product [id=102, name=Rice, quantity=502, price=58.19]
Product [id=103, name=Lentils, quantity=803, price=102.45]
Product [id=104, name=Oil, quantity=208, price=164.75]
2.2 Sort Student list according to their Percentage
- Student class is defined with 3 attributes namely rollNumber, name and their percentage
- Along with 3 attributes, parameterized constructor, getters/setters and toString() method is defined – removed for brevity
- Member variable percentage is of type primitive double
Student.java
package net.bench.resources.comparator.comparingdouble;
public class Student {
// member variables
private int rollNumber;
private String name;
private double percentage;
// 3-arg parameterized constructors
// getters & setters
// toString()
}
SortStudentListByPercentage.java
- A list contains 5 Student information as per insertion-order
- Sorting :- we are going to sort the Student list in the increasing order of Student‘s Percentage using Collections.sort() method passing Comparator.comparingDouble() as 2nd argument and original list as 1st argument
- Comparator.comparingDouble() accepts ToDoubleFunction which means it accepts key of double type only
package net.bench.resources.comparator.comparingdouble;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SortStudentListByPercentage {
// List of Students
private static List<Student> getStudentList() {
return Arrays.asList(
new Student(2033, "Viraj", 65.67),
new Student(2020, "Rishi", 91.97),
new Student(2004, "Aditya", 78.13),
new Student(2015, "Krish", 35.32),
new Student(2037, "Suresh", 51.02)
);
}
public static void main(String[] args) {
// 1. get Student list
List<Student> studentList = getStudentList();
// 1.1 print to console
System.out.println("Student list as per Insertion-order :-\n");
studentList.forEach(System.out::println); // iterate/printing
// 2. sorting Student list in ascending-order of Student's Percentage
System.out.println("\n\nSorted Student list by their Percentage :-\n");
// 2.1 sorting using Collections.sort() & Comparator
Collections.sort(
studentList, // original list
Comparator.comparingDouble(Student::getPercentage) // double sorting
);
// 2.2 print to console
studentList.forEach(System.out::println); // iterate/printing
}
}
Output:
Student list as per Insertion-order :-
Student [rollNumber=2033, name=Viraj, percentage=65.67]
Student [rollNumber=2020, name=Rishi, percentage=91.97]
Student [rollNumber=2004, name=Aditya, percentage=78.13]
Student [rollNumber=2015, name=Krish, percentage=35.32]
Student [rollNumber=2037, name=Suresh, percentage=51.02]
Sorted Student list by their Percentage :-
Student [rollNumber=2015, name=Krish, percentage=35.32]
Student [rollNumber=2037, name=Suresh, percentage=51.02]
Student [rollNumber=2033, name=Viraj, percentage=65.67]
Student [rollNumber=2004, name=Aditya, percentage=78.13]
Student [rollNumber=2020, name=Rishi, percentage=91.97]
2.3 Throws NullPointerException if argument is NULL
- If the input argument to Comparator.comparingDouble() method is null then it throws NullPointerException as shown in the below illustration
- Check How to sort List and Arrays with null values to handle list with null values while sorting
SortProductListWithNullPresent.java
package net.bench.resources.comparator.comparingdouble;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class SortProductListWithNullPresent {
// List of Products
private static List<Product> getProductList() {
return Arrays.asList(
new Product(102, "Rice", 502L, 58.19),
new Product(104, "Oil", 208L, 164.75),
new Product(103, "Lentils", 803L, 102.45),
new Product(105, "Vegetables", 303L, 45.50),
new Product(101, "Wheat", 1089L, 36.89)
);
}
public static void main(String[] args) {
// 1. get Product list
List<Product> products = getProductList();
// 2. sorting Product list in ascending-order by its Id
System.out.println("Exception - Sorted Product list with Null value :-\n");
// 3. sorting/iterating/printing
products
.stream() // 1. get sequential stream
.sorted(Comparator.comparingDouble(null)) // 2. null
.forEach(System.out::println); // 3. iterate/printing
}
}
Output:
Exception - Sorted Product list with Null value :-
Exception in thread "main" java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Comparator.comparingDouble(Comparator.java:530)
at net.bench.resources.comparator.comparingdouble.SortProductListWithNullPresent
.main(SortProductListWithNullPresent.java:35)
References:
- https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html
- https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#comparingDouble-java.util.function.ToDoubleFunction-
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
- https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html
- https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html
Happy Coding !!
Happy Learning !!