Last active
October 26, 2021 17:08
-
-
Save bbottema/b891b25bf56e0ccb1f83 to your computer and use it in GitHub Desktop.
Demonstration of various techniques for sorting based on multiple properties. Also, see: http://www.bennybottema.com/2013/06/21/ways-to-sort-lists-of-objects-in-java-based-on-multiple-fields/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Collections; | |
import java.util.Comparator; | |
import java.util.List; | |
import com.google.common.collect.ComparisonChain; | |
import org.apache.commons.beanutils.BeanComparator; | |
import org.apache.commons.collections.comparators.ComparatorChain; | |
import org.apache.commons.lang3.builder.CompareToBuilder; | |
public class PizzaSorter { | |
public static void main(String[] args) { | |
List<Pizza> pizzas = new ArrayList<>(); | |
// size cm, number of toppings, name and expected index after sorting | |
pizzas.add(new Pizza(30, 4, "Pizza A", 4)); | |
pizzas.add(new Pizza(30, 4, "Pizza B", 3)); | |
pizzas.add(new Pizza(30, 8, "Pizza C", 2)); | |
pizzas.add(new Pizza(30, 8, "Pizza D", 1)); | |
pizzas.add(new Pizza(20, 4, "Pizza E", 8)); | |
pizzas.add(new Pizza(20, 4, "Pizza F", 7)); | |
pizzas.add(new Pizza(20, 8, "Pizza G", 6)); | |
pizzas.add(new Pizza(20, 8, "Pizza H", 5)); | |
printPizzaList("by hand", sortByHand(pizzas)); | |
printPizzaList("using reflection", sortReflective(pizzas)); | |
printPizzaList("using google guava", sortGuava(pizzas)); | |
printPizzaList("using apache commons", sortApacheCommons(pizzas)); | |
} | |
private static List<Pizza> sortByHand(List<Pizza> pizzas) { | |
Collections.sort(pizzas, new Comparator<Pizza>() { | |
@Override | |
public int compare(Pizza p1, Pizza p2) { | |
int sizeCmp = p1.size.compareTo(p2.size); | |
if (sizeCmp != 0) { | |
return sizeCmp; | |
} | |
int nrOfToppingsCmp = p1.nrOfToppings.compareTo(p2.nrOfToppings); | |
if (nrOfToppingsCmp != 0) { | |
return nrOfToppingsCmp; | |
} | |
return p1.name.compareTo(p2.name); | |
} | |
}); | |
return pizzas; | |
} | |
private static List<Pizza> sortReflective(List<Pizza> pizzas) { | |
Collections.sort(pizzas, new ComparatorChain(Arrays.asList( | |
new BeanComparator("size"), | |
new BeanComparator("nrOfToppings"), | |
new BeanComparator("name")))); | |
return pizzas; | |
} | |
private static List<Pizza> sortGuava(List<Pizza> pizzas) { | |
Collections.sort(pizzas, new Comparator<Pizza>() { | |
@Override | |
public int compare(Pizza p1, Pizza p2) { | |
return ComparisonChain.start() | |
.compare(p1.size, p2.size/*, Ordering.natural().nullsLast()*/) | |
.compare(p1.nrOfToppings, p2.nrOfToppings/*, Ordering.natural().nullsLast()*/) | |
.compare(p1.name, p2.name/*, Ordering.natural().nullsLast()*/) | |
.result(); | |
} | |
}); | |
return pizzas; | |
} | |
private static List<Pizza> sortApacheCommons(List<Pizza> pizzas) { | |
Collections.sort(pizzas, new Comparator<Pizza>() { | |
@Override | |
public int compare(Pizza p1, Pizza p2) { | |
return new CompareToBuilder() | |
.append(p1.size, p2.size) | |
.append(p1.nrOfToppings, p2.nrOfToppings) | |
.append(p1.name, p2.name) | |
.toComparison(); | |
} | |
}); | |
return pizzas; | |
} | |
private static void printPizzaList(String sortingMethod, List<Pizza> pizzas) { | |
System.out.println("Pizza's sorted using method: " + sortingMethod); | |
for (Pizza pizza : pizzas) { | |
System.out.println(String.format("%s (index: %s)", pizza.name, pizza.index)); | |
} | |
} | |
public static class Pizza { | |
private final Integer size; | |
private final Integer nrOfToppings; | |
private final String name; | |
private final Integer index; | |
public Pizza(Integer size, Integer nrOfToppings, String name, Integer index) { | |
this.size = size; | |
this.nrOfToppings = nrOfToppings; | |
this.name = name; | |
this.index = index; | |
} | |
public Integer getSize() { | |
return size; | |
} | |
public Integer getNrOfToppings() { | |
return nrOfToppings; | |
} | |
public String getName() { | |
return name; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment