There is a list with objects. It is necessary to sort this list from different situations by different values ​​of the class fields. Example:

public static void doSort(List<Mix> array, int start, int end, int type) { if (start >= end) return; int i = start, j = end; int cur = i - (i - j) / 2; while (i < j) { switch (type) { case 1: { while (i < cur && (array.get(i).getCost() <= array.get(cur).getCost())) { i++; } while (j > cur && (array.get(cur).getCost() <= array.get(j).getCost())) { j--; } } break; case 2: { while (i < cur && (array.get(i).getBaseCost() <= array.get(cur).getBaseCost())) { i++; } while (j > cur && (array.get(cur).getMaxSpeed() <= array.get(j).getMaxSpeed())) { j--; } } break; } if (i < j) { Collections.swap(array,i,j); if (i == cur) cur = j; else if (j == cur) cur = i; } } doSort(array, start, cur, type); doSort(array, cur+1, end, type); } 

Depending on the parameter passed, sorting is performed according to one or another field, the field is selected using switch.

Is it possible to get away from switch? Is sorting more flexible (via parameterized method, overload) in this case?

  • one
    Transfer the necessary comparator simply - iksuy
  • @iksuy, can I have an example or source for reading? - studentST

2 answers 2

You can create the necessary Comparator and use them in a specific situation:

 private static class Element { private final int cost, baseCost, speed; public Element(int cost, int baseCost, int speed) { this.cost = cost; this.baseCost = baseCost; this.speed = speed; } public int getCost() { return cost; } public int getBaseCost() { return baseCost; } public int getSpeed() { return speed; } public String toString() { return "{" + cost + " " + baseCost + " " + speed + "}"; } } private static final Comparator<Element> comparatorElementCost = (Element e1, Element e2) -> (e1.getCost() - e2.getCost()); private static final Comparator<Element> comparatorElementBaseCost = (Element e1, Element e2) -> (e1.getBaseCost() - e2.getBaseCost()); private static final Comparator<Element> comparatorElementSpeedCost = (Element e1, Element e2) -> (e1.getSpeed() - e2.getSpeed()); public static void main(String[] args) { List<Element> list = Arrays.asList(new Element(1, 20, 300), new Element(2, 10, 200), new Element(3, 30, 100)); list.sort(comparatorElementCost); System.out.println(list); list.sort(comparatorElementBaseCost); System.out.println(list); list.sort(comparatorElementSpeedCost); System.out.println(list); } 

You can also create the desired comparator using the Comparator.comparing method:

 private static final Comparator<Element> comparatorElementCost = Comparator.comparing(Element::getCost); 

If you do not intend to use the comparator often, then you can not put it into a variable:

 list.sort(Comparator.comparing(Element::getCost)); 

    You can also not create Comparator using Java 8 Stream API

     public class B { String s; Long i; public B() { s = String.valueOf(System.currentTimeMillis()); i = System.currentTimeMillis(); } public String getS() { return s; } public Long getI() { return i; } } public static void main(String[] args) throws InterruptedException { B b1 = new B(); Thread.sleep(222L); B b2 = new B(); List<B> list = Arrays.asList(b2,b1,b2,b1,b2,b1); List<B> sSort = list.stream().sorted(Comparator.comparing(b -> b.getS())).collect(Collectors.toList()); List<B> iSort = list.stream().sorted(Comparator.comparing(b -> b.getI())).collect(Collectors.toList()); } 
    • Generally speaking, the comparator is still being created. Simply, it is not assigned to a variable, but is immediately passed to the method. - Regent