Подскажите как заменить 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 шт):
Возьмите за основу 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 пути:
- писать свой класс, выполняющий сортировку (треш редкий);
- возложить эту почетную обязанность на базу данных, если, конечно , она есть (в чем я в данном случае сомневаюсь);
- использовать механизмы сортировки 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. И снова у вас два пути:
у листа есть метод
list.sort(comparator), именно в аргументы этого метода и передается экземпляр класса, а котором мы имплементировали компаратор, поскольку таких классов мы можем написать много, то и сортировать можем по разным критериям;статический метод утилитного класса
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());
}
}