Skip to content

Instantly share code, notes, and snippets.

@bbottema
Last active October 26, 2021 17:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bbottema/b891b25bf56e0ccb1f83 to your computer and use it in GitHub Desktop.
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/
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