1. Try TreeSet with Comparator and Comparable
In Java, TreeSet is a member of the Java Collection Framework. Elements of the TreeSet are ordered by using their natural ordering, or by a Comparator. A Big-O notation of tree but not specific to Java refers to a pretty good website: bigocheatsheet.com
Java supports two interfaces to make a comparison: Comparable and Comparator. Each of these provides one method to be implemented by user.
java.lang.Comparable | java.util.Comparator |
---|---|
int o1.compareTo(T o2) | int compare(T o1, T o2) |
-1, 0, or 1 as this object is less than, equal to, or greater than the specified object. | Same as Comparable |
Must modify the class whose instance you want to sort | Build your own class separating from the class whose instance you want to sort. |
Be able to create only one sort sequence. | Many sort sequences. |
Being implemented frequently to sort in the API by: String, Wrapper Class, Calendar… | To sort instance of third-party classes. |
Example
Car.java
/** * The Car class holds information and provides methods common to all cars. */ public class Car implements Comparable<Car> { private int serialNumber; private String manufacturerName; private int basePrice; /** * Construct a new Car. */ public Car(int serialNumber, int basePrice, String manufacturerName) { this.serialNumber = serialNumber; this.basePrice = basePrice; this.manufacturerName = manufacturerName; } public int getBasePrice() { return basePrice; } public String getManufacturerName() { return manufacturerName; } public int compareTo(Car o) { return this.serialNumber - o.serialNumber; } @Override public String toString() { return this.serialNumber + " " + this.manufacturerName + " " + this.basePrice; } }
CarSorted.java
public class CarSorted implements Comparator<Car> { public int compare(Car o1, Car o2) { // Compare with manufacturer name if (!o1.getManufacturerName().equals(o2.getManufacturerName())) { return o1.getManufacturerName().compareTo(o2.getManufacturerName()); } else { // Compare with basePrice if (o1.getBasePrice() > o2.getBasePrice()) { return 1; } else if (o1.getBasePrice() < o2.getBasePrice()) { return -1; } else { return 0; } } } }
CarTest.java
import java.util.Set; import java.util.TreeSet;; public class CarTest { public static void main(String[] args) { Set<Car> treeSet = new TreeSet<Car>(); treeSet.add(new Car(8849480, 50000, "Toyota")); treeSet.add(new Car(7894848, 120000, "Honda")); treeSet.add(new Car(3747375, 70000, "Ford")); System.out.println("List of cars sorted by comparable: serialNumber"); for (Car car : treeSet) { System.out.println(car.toString()); } Set<Car> treeSet1 = new TreeSet<Car>(new CarSorted()); treeSet1.add(new Car(8849480, 50000, "Toyota")); treeSet1.add(new Car(7894848, 120000, "Honda")); treeSet1.add(new Car(3747375, 70000, "Ford")); treeSet1.add(new Car(3747305, 60099, "Ford")); System.out.println("List of cars sorted by comparator:" + " manufacturerName, basePrice"); for (Car car : treeSet1) { System.out.println(car.toString()); } } }
Output
List of cars sorted by comparable: serialNumber 3747375 Ford 70000 7894848 Honda 120000 8849480 Toyota 50000 List of cars sorted by comparator: manufacturerName, basePrice 3747305 Ford 60099 3747375 Ford 70000 7894848 Honda 120000 8849480 Toyota 50000
2. Update Sorting in Java 8 Lambda
In this example, we will try to present a Sorting strategies to sort a list of Countries.
2.1 Sorting strategies.
Apply different ordering solutions: behavior parameterization, anonymous classes, lambda
expressions, and method references.
import java.util.Arrays; import java.util.Comparator; import java.util.List; import static java.util.Comparator.comparing; public class Sorting { public static void main(String... args) { List<Country> countries = Arrays.asList( new Country("US","United States","en"), new Country("AF","Afghanistan","af") ); // 1. Pass code // [Country {code=AF, name=Afghanistan, localizationLang=af}, // Country {code=US, name=United States, localizationLang=en}] countries.sort(new CountryComparator()); System.out.println(countries); // reshuffling things a little countries.set(0, new Country("ZA","South Africa","en")); // 2. Use an anonymous class // [Country {code=US, name=United States, localizationLang=en}, // Country {code=ZA, name=South Africa, localizationLang=en}] countries.sort( new Comparator<Country>() { @Override public int compare(Country c1, Country c2) { return c1.getCode().compareTo(c2.getCode()); } }); System.out.println(countries); // reshuffling things a little countries.set(0, new Country("GB","United Kingdom","en")); // 3. Use lambda expressions // [Country {code=GB, name=United Kingdom, localizationLang=en}, // Country {code=ZA, name=South Africa, localizationLang=en}] countries.sort((c1, c2) -> c1.getCode().compareTo(c2.getCode())); System.out.println(countries); // reshuffling things a little countries.set(1, new Country("BE","Belgium","nl")); // 4. Use method references. // which make your code slightly less verbose and more readable // assuming a static import of java.util.Comparator.comparing // [Country {code=BE, name=Belgium, localizationLang=nl}, // Country {code=GB, name=United Kingdom, localizationLang=en}] countries.sort(comparing(Country:: getCode)); System.out.println(countries); } public static class Country { private String code; private String name; private String localizationLang; public Country(String code, String name, String localizationLang) { this.code = code; this.name = name; this.localizationLang = localizationLang; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLocalizationLang() { return localizationLang; } public void setLocalizationLang(String localizationLang) { this.localizationLang = localizationLang; } @Override public String toString() { return "Country {code=" + code + ", name=" + name + "," + " localizationLang=" + localizationLang + "}"; } } public static class CountryComparator implements Comparator<Country> { @Override public int compare(Country o1, Country o2) { return o1.getCode().compareTo(o2.getCode()); } } }
2.2 Sort a list of countries by code in ascending order.
public static void main(String[] args) { List<Country> countries = Arrays.asList( new Country("US","United States","en"), new Country("AF","Afghanistan","af"), new Country("BE","Belgium","nl"), new Country("ZA","South Africa","en"), new Country("GB","United Kingdom","en") ); Comparator<Country> countryNameComparator = (c1, c2) -> (c1.getName().compareTo(c2.getName())); // Sort the countries in ascending order only. countries.sort(countryNameComparator); // Sort the countries in ascending order and using English language. List<Country> countrySortByAsc = countries.stream() .filter(c ->"en".equals(c.getLocalizationLang())) .sorted(countryNameComparator).collect(Collectors.toList()); }
Output
Afghanistan AF af Belgium BE nl South Africa ZA en United Kingdom GB en United States US en [South Africa ZA en, United Kingdom GB en, United States US en]
2.3 Reversed sorting
// To sort the records in a descending order, you can use reversed order List<Country> countrySortByDesc = countries.stream() .filter(c ->"en".equals(c.getLocalizationLang())) .sorted(countryNameComparator.reversed()).collect(Collectors.toList()); // The same reversed order countries.sort(countryNameComparator.reversed());
Output
[United States US en, United Kingdom GB en, South Africa ZA en]
References:
- Raoul-Gabriel Urma, Mario Fusco, and Alan Mycrof, “Method References”, in Java 8 in Action: Lambdas, streams, and functional-style programming, pp. 82-92, Manning Publications, 2015.
- Oracle Java Document, “Object Ordering”. Accessed 23 April, 2016. https://docs.oracle.com/javase/tutorial/collections/interfaces/order.html
- “Interface Comparable
,” Oracle Java Platform Standard Ed.7. Accessed Jan 30, 2016, https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html. - “Interface Comparator
,” Oracle Java Platform Standard Ed.7. Accessed Jan 30, 2016, https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html. - “Class TreeSet
,” Oracle Java Platform Standard Ed.7. Accessed Jan 30, 2016, https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html. - “Interface Comparator” Oracle Java Platform Standard Ed.8. Accessed July 27, 2016, https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html