Подскажите как заменить Collections в классе

Есть класс, в котором сортировка производится в коллекции... Как заменить коллекцию на что-то другое (более "упрощенное"), при этом сохранив сортировку и т.д.?

import java.util.Collections;
import java.util.Comparator;

public class AirlineSorter {
    /*
     * Method sorting planes in airline fleet by it's flight range:
     * put's the plane with lowest flight range parameter to the
     * begging of airline planes list, plane with highest flight
     * range to the end of airline planes list.
     *
     * @param airline airline
     */
    public void sortPlanesByFlightRange(Airline airline) {
        Comparator<Plane> comparator = new Comparator<Plane>() {
            @Override
            public int compare(Plane o1, Plane o2) {
                if (o1.getFlightRange() - o2.getFlightRange() > 1) {
                    return 1;
                } else if (o1.getFlightRange() - o2.getFlightRange() < 1) {
                    return -1;
                } else {
                    return 0;
                }
            }
        };
        Collections.sort(airline.getFleet().getPlanes(), comparator);
    }
}

Ответы (2 шт):

Автор решения: Aziz Umarov

Возьмите за основу quickSort

public void quickSort(Plane arr[], int begin, int end) {
    if (begin < end) {
        int partitionIndex = partition(arr, begin, end);
 
        quickSort(arr, begin, partitionIndex-1);
        quickSort(arr, partitionIndex+1, end);
    }
}


private int partition(Plane arr[], int begin, int end) {
Plane pivot = arr[end];
int i = (begin-1);

for (int j = begin; j < end; j++) {
    if (comparator.compare(arr[j], pivot)<=0) {
        i++;

        Plane swapTemp = arr[i];
        arr[i] = arr[j];
        arr[j] = swapTemp;
    }
}

Plane swapTemp = arr[i+1];
arr[i+1] = arr[end];
arr[end] = swapTemp;

return i+1;
}

И реализуйте sort и замените List.

→ Ссылка
Автор решения: Дмитрий

Вы снова заходите не с той стороны. Для сортировки есть всего 3 пути:

  1. писать свой класс, выполняющий сортировку (треш редкий);
  2. возложить эту почетную обязанность на базу данных, если, конечно , она есть (в чем я в данном случае сомневаюсь);
  3. использовать механизмы сортировки Java.

Остановимся на последнем пункте.

Вы должны понимать, что с одной стороны есть данные, которые сортируются (в данном случае это класс Plane). Разумеется, экземпляров этих классов несколько (иначе нечего будет сортировать), и также разумеется, что этих самых несколько экземпляров надо где-то хранить (фактически объявить переменную, на это способную). И тут всего 2 варианта - коллекции (и их очень много на любую задачу и это не только родные джавовские, но и множество сторонних реализаций от гугла, апача и т.д, что дает максимальную гибкость) и массивы.

Теперь вернемся к модели. Ваша модель содержит множество полей и, разумеется, для сортировки нужно описать логику этой самой сортировки. Для описания этой логики используется 2 интерфейса Comparable и Comparator. Оба работают с помощью дженериков. В случае с Comparable его должна имплементировать сама модель (Plane, соответвенно при имплементации мы напишем дженерик implements Comparable <Plane>, чтобы в аргументах метода, который предстоит переопределит работать с объектом Plane, а не Object). При этом от вас потребуется переопределние метода compare, как уже сказано, принимающий экземпляр класса Plane, где вы и опишите логику сравнения принимаемого объекта со своим текущим объектом. Это работает до тех пор, пока у вас единственный критерий сравнения.

Если же вам в разных местах бизнесс-логики необходимо сортировать по разным критериям, то Comparable вам не подойдет (ведь метод compare дважды в одном классе не переопределишь), и тогда вам нужен Comparator. Здесь подход немного другой. Для каждого отдельного критерия сортировки мы создаем отдельный класс, именно этот класс, а не сама модель, теперь будет имплементировать Comparator (он тоже с дженериком, поэтому пишем аналогично предыдущему implements Comparator <Plane>). И опять нужно переопределить единственный метод compareTо, но он уже принимает 2 аргумента (2 экземпляра класса Plane, ведь с текущим, т.е. this уже не сравнишь, это же отдельный от модели класс). Логика переопределения аналогичная.

Теперь другая сторона медали - место в коде откуда непосредствено осуществляется вызов сортировки. В этом случае у вас уже есть либо коллекция Plane (поддающаяся сортировке, потому как, к примеру, HashSet отсортировать нельзя), либо массив Plane, который нужно отсортировать. В первом случае (не рассматривая тяжелые случаи) это имплементации интерфейса List. И снова у вас два пути:

  1. у листа есть метод list.sort(comparator), именно в аргументы этого метода и передается экземпляр класса, а котором мы имплементировали компаратор, поскольку таких классов мы можем написать много, то и сортировать можем по разным критериям;

  2. статический метод утилитного класса Collections.sort(list, comparator), который перегружен и может быть вызван с одним аргументом Collections.sort(list), первый случай аналогичен вызову у листа - передаем наш лист и экземпляр класса, имплементирующего компаратор, второй случай нужен в том случае, если вы использовали не Comparator, а Comparable, следовательно, "научили" непосредственно модель выполнять сортировку.

    Что касается массива, тут все идентично Collections, но вместо последнего мы используем утилитный класс Arrays, его методы полностью сходны с методами Collections, только теперь вместо листа массив - Arrays.sort(array, comparator) и Arrays.sort(array). Вот и все...

И последнее... Когда имплементируете Comparator или Comparable, то используйте в модели не примитивы, а ссылочные типы, ведь для них уже переопределены все нужные вам методы. Тогда не нужно писать условные операторы и возвращать -1,1,0, как вы делали, а достаточно сделать так:

import java.util.Comparator;

public class FlightRangeSorter implements Comparator<Plane>{
    @Override
    public int compare(Plane o1, Plane o2) {
        return o1.getFlightRange().compareTo(o2.getFlightRange());
    }
} 
→ Ссылка