Сортировка объектов в списке на основе строковых меток - PullRequest
0 голосов
/ 07 августа 2020

У меня есть список объектов, которые я реализую с помощью специального компаратора, чтобы отсортировать их в желаемый мной формат.

Мой объект выглядит следующим образом

storageZoneId = <a long value>
floorNo = <an integer>
status = <CREATED/DRAFT>

Я хочу мой список объектов для сортировки таким образом, чтобы они были упорядочены сначала по всем статусам DRAFT, затем по StorageZoneId, а затем по floorNo. То, что я реализовал до сих пор, выполняет последние два шага, но как я могу сделать первый - в основном разделить список так, чтобы за всеми статусами «ЧЕРНОВИК» сначала следовали все «СОЗДАНО».

public int compare(Object o1, Object o2) {
        ServiceRequest serviceRequest1 = (ServiceRequest) o1;
        ServiceRequest serviceRequest2 = (ServiceRequest) o2;
        int compare_zone = Long.compare(serviceRequest1.getStorageZoneId(), serviceRequest2.getStorageZoneId());
        if (compare_zone == 0) {
            return Integer.compare(serviceRequest1.getFloorNumer(), serviceRequest2.getFloorNumer());
        } else {
            return compare_zone;
        }
    }

Ответы [ 3 ]

2 голосов
/ 07 августа 2020

Используя Java 8+, вы можете создать свой компаратор другим способом:

//put this somewhere so you don't recreate it everytime
Map<String, Integer> statusOrder = new HashMap<>();
statusOrder.put("DRAFT", 1);
statusOrder.put("CREATED", 2);  

Comparator<ServiceRequest> comp = Comparator.comparing(sr -> statusOrder.get(sr.getStatus()))
                                    .thenComparing(ServiceRequest::getStorageZoneId)
                                    .thenComparing(ServiceRequest::getFloorNumer);

(Примечание: синтаксис может содержать ошибку, так как я написал это в голове, не имея доступа к компилятор atm)

1 голос
/ 07 августа 2020
enum Status {
    DRAFT,
    CREATED
}

class MyObject {
    long storageZoneId;
    int floorNo;
    Status status;

    public MyObject(long storageZoneId, int floorNo, Status status) {
        this.storageZoneId = storageZoneId;
        this.floorNo = floorNo;
        this.status = status;
    }

    public long getStorageZoneId() {
        return storageZoneId;
    }

    public int getFloorNo() {
        return floorNo;
    }

    public Status getStatus() {
        return status;
    }

    @Override
    public String toString() {
        return "MyObject{" +
                "storageZoneId=" + storageZoneId +
                ", floorNo=" + floorNo +
                ", status=" + status +
                '}';
    }
}

public static void main(String[] args) {
        List<MyObject> myObjectList = new ArrayList<>();
        myObjectList.add(new MyObject(1, 5, Status.DRAFT));
        myObjectList.add(new MyObject(3, 2, Status.DRAFT));
        myObjectList.add(new MyObject(4, 3, Status.CREATED));
        myObjectList.add(new MyObject(6, 8, Status.CREATED));

        Comparator<MyObject> comparator = Comparator.comparing(MyObject::getStatus)
                .thenComparing(MyObject::getStorageZoneId)
                .thenComparing(MyObject::getFloorNo);

        myObjectList.sort(comparator);

        for (MyObject obj : myObjectList) {
            System.out.println(obj);
        }
    }

Чтобы добавить к другому ответу, вы можете использовать построитель Comparator, чтобы упростить logi c Comparator. Поле состояния определяется как перечисление, и перечисления сортируются на основе относительного порядка, в котором значения перечисления появляются в определении перечисления. Таким образом, ваш список сначала будет отсортирован по статусу DRAFT, так как он сначала появляется в перечислении, а затем по статусу CREATED.

1 голос
/ 07 августа 2020

Я считаю, что что-то вроде этого должно помочь:

public int compare(Object o1, Object o2) {
        ServiceRequest serviceRequest1 = (ServiceRequest) o1;
        ServiceRequest serviceRequest2 = (ServiceRequest) o2;

        if (o1.getStatus().equals("DRAFT") && o2.getStatus().equals("CREATED")){
            return 1;
        }
        if (o1.getStatus().equals("CREATED") && o1.getStatus().equals("DRAFT")){
            return -1;
        }

        int compare_zone = Long.compare(serviceRequest1.getStorageZoneId(), serviceRequest2.getStorageZoneId());
        if (compare_zone == 0) {
            return Integer.compare(serviceRequest1.getFloorNumer(), serviceRequest2.getFloorNumer());
        } else {
            return compare_zone;
        }
    }

Если статус o1 - «ЧЕРНОВИК», а статус o2 - «СОЗДАН», тогда o1 идет первым. точно - вернуть 1. Во втором сравнении ситуация обратная. Только если статус обоих одинаковый, тогда важны другие поля, мы просто продолжим то, что у вас есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...