сортировать по обнуляемому полю с указанием позиции элемента - PullRequest
0 голосов
/ 04 декабря 2018

Мне нужно отсортировать массив объектов по-своему.Допустим, у меня есть два поля в моих объектах - priority (обнуляемый) и createdAt (не обнуляемый).В поле приоритета указывается, в каком положении должен быть элемент.Однако это может быть нулевым.В этом случае мы должны выполнить сортировку с учетом поля createAt (в порядке убывания).

Позвольте мне объяснить это на примере.Например, мои объекты будут:

Object0: priority: null, createdAt: 2018-12-01
Object1: priority: 1,    createdAt: 2018-12-02
Object2: priority: 5,    createdAt: 2018-12-03
Object3: priority: null, createdAt: 2018-12-04
Object4: priority: null, createdAt: 2018-12-05
Object5: priority: 2,    createdAt: 2018-12-06
Object6: priority: null, createdAt: 2018-12-07

Окончательный порядок должен быть:

  1. Object1 (по приоритету)
  2. Object5 (по приоритету)
  3. Object6 (заполнение левых позиций с помощью creatAt desc)
  4. Object4 (заполнение левых позиций с помощью creatAt desc)
  5. Object2 (по приоритету)
  6. Object3 (заполнениелевые позиции с помощью createAt desc)
  7. Object0 (заполнение левых позиций с помощью creatAt desc)

Как мне достичь своей цели?Готов ли какой-нибудь готовый компаратор?

РЕДАКТИРОВАТЬ: Я думаю, мы можем использовать этот класс:

public class MyObject {
   Integer priority;
   LocalDateTime createdAt;
}

Ответы [ 3 ]

0 голосов
/ 04 декабря 2018

Учитывая список всех объектов: массив будет хорошо, чтобы установить позицию от приоритета:

List<MyObject> list = new ArrayList<>(Arrays.asList(...));
MyObject[] res = new MyObject[list.size()];
  1. Перебирать объекты, которые вы должны разместить те, которыеиметь приоритет

    for (Iterator<MyObject> ite = list.iterator(); ite.hasNext(); ) {
        MyObject obj = ite.next();
        if (obj.getPriority() != null) {
            res[obj.getPriority() - 1] = obj;
            ite.remove();
        }
    }
    
  2. Сортировать остальные по убыванию createdAt

    list.sort(Comparator.comparing(MyObject::getCreatedAt).reversed());
    
  3. Вставить их в пустые поля массива

    int indicList = 0;
    for (int i = 0; i < res.length; i++) {
        if (res[i] == null) {
            res[i] = list.get(indicList++);
        }
    }
    

0 голосов
/ 04 декабря 2018

Один из возможных способов (не очень уверенных в эффективности) использования потоков:В списке установлен приоритет 0.- Значения ненулевого приоритета являются точными индексами в finalList

0 голосов
/ 04 декабря 2018

Нет, не используйте компаратор для этого, или, точнее, не для всей работы.Задача компаратора состоит в том, чтобы сравнить два объекта и определить порядок между этими двумя объектами.Он не подходит для обнаружения пропусков в последовательности приоритетов.

Вместо этого, предполагая, что приоритеты являются интегральными и уникальными, я предлагаю использовать массив и своего рода сортировку по осям для объектов с определенными приоритетами.Приоритет 1 включается в индекс массива 1, индекс приоритета 2 и т. Д. Объекты с приоритетом null сортируются с помощью компаратора по убыванию даты создания, а затем заполняются в индексы массива, которые все еще равны null (кроме индекса 0,Я думаю).

Под «предположением, что приоритеты являются интегральными и уникальными», я имею в виду, что вы не рискуете двумя объектами с приоритетом 3 или объектом с приоритетом 2.44.

Я мог бы использоватьstream и Collectors.partitioningBy, чтобы отделить объекты с приоритетами от объектов без приоритета, но, конечно, есть и другие способы.

Я бы написал это вручную.Я никогда не слышал ни о каком готовом решении для этого.Поиск никогда не вредит, но я был бы удивлен, найдя его.С другой стороны, не нужно много строк кода.

Кстати, используйте LocalDate для ваших дат, поскольку у них нет времени суток (не LocalDateTime).

...