Comparing Objects in Java - Lambdas
Sorting has come a log way since Java was created. Techniques have changed. There was huge change when JDK1.5 was launched. JDK1.7 involved a somewhat more changes but JDK1.8 had considerable changes like lambdas. Lambdas not only gave a new perspective for one liner functions or anonymous classes but also eased a lot of coding complexities or reduced Lines of code.
With that said, sorting a list of objects has been a lot more comfortable as well. We have already talked about how we sort using Comparators and Comparable. You can visit that discussion here.
Let's say you want to sort a list. Without Lambdas you'll create a comparator and pass it to the sort method of Collections class.
But, before we do that, Let's create a Product class that has the properties of a product and regular Getter and Setters. You can download the complete class from github. If you are downloading the code from github, then it has some Jackson related annotations. If you are using your own project then remove them. If you have downloaded the entire Project then it can be run as is. We will be sorting a list of products.
public class Product {
private String productID;
private String sku;
private String name;
private Double price;
private Double retailPrice;
private String brand;
private Double ratingavg;
private Integer ratingCount;
private Integer inventoryCount;
private LocalDateTime dateCreated;
// getter and setters
}
Let's try and sort the Product class by name
Collections.sort(productList, new Comparator<Product>() {
@Override
public int compare(Product p1, Product p2) {
return p1.getName().compareTo(p2.getName());
}
});
With Lambdas you can do the same by replacing the anonymous class with the simple lambda expression. Note, we started using the sort method of the list and not Collections.
productList.sort((p1, p2) -> p1.getName().compareTo(p2.getName()));
Looks a bit neater now. Observe now that we are no longer required to give type definitions for objects p1 and P2. Compiler is smart enough to decode that by default.
Now, Lets write static methods in the Product class. These functions will except two products and will return an int. Signature is similar to a compare function.
public static int compareByNameThenRating(Product lhs, Product rhs) {
if (lhs.name.equals(rhs.name)) {
return Double.compare(lhs.ratingavg, rhs.ratingavg);
} else {
return lhs.name.compareTo(rhs.name);
}
}
public static int compareByBrandThenName(Product lhs, Product rhs) {
if (lhs.brand.equals(rhs.brand)) {
return lhs.name.compareTo(rhs.name);
} else {
return lhs.brand.compareTo(rhs.brand);
}
}
Understanding the above functions should be simple. We are trying to compare by one property, if these properties are equal then will sort by another one.
After you have written the functions, these static functions can be used as a static reference in lambda functions.
productList.sort(Product::compareByNameThenRating);
productList.sort(Product::compareByBrandThenName);
If we want to still use the Collections class sort method, we can do that as below.
Collections.sort(productList, Comparator.comparing(Product::getPrice));
If you want to chain multiple sorting properties, you do that as well.
productList.sort(Comparator.comparing(Product::getBrand).thenComparing(Product::getName));
end
Comments
Post a Comment