根据字符串标签对列表中的对象进行排序

时间:2020-08-07 07:37:06

标签: java

我有一个对象列表,这些对象正在实现自定义比较器,以按照我期望的格式将它们分类。

我的对象如下所示

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

我希望对对象列表进行排序,以使它们首先按所有DRAFT状态排序,然后按StorageZoneId然后按floorNo排序。到目前为止,我已经实现了最后两个步骤,但是我该如何做第一个步骤-基本上将列表拆分成所有“ DRAFT”状态都紧随其后的是“ CREATED”。

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 个答案:

答案 0 :(得分:2)

使用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 :(得分:1)

我相信类似的方法应该可以解决问题

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的状态为“ DRAFT”,而o2的状态为“ CREATED”,那么肯定会首先出现o1-返回1。在第二个比较中,情况相反。仅当两者的状态相同时,其他字段才重要,我们将继续您到目前为止的操作。

答案 2 :(得分:1)

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);
        }
    }

只需添加到其他答案中,您就可以使用“比较器”构建器来简化比较器逻辑。 status字段被定义为枚举,并且枚举根据枚举值在枚举定义中出现的相对顺序进行排序。因此,您的列表将首先按照DRAFT状态(首先出现在枚举中,然后是CREATED状态)进行排序。