英文:
Sort objects in a List based on String labels
问题
我有一个对象列表,我正在实现一个自定义比较器,将它们按照我期望的格式排序。
我的对象看起来像这样:
storageZoneId = <一个长整数值>
floorNo = <一个整数>
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;
}
}
英文:
I have a list of objects that I am implementing a custom Comparator to sort them into the format as desired by me.
My object looks like the following
storageZoneId = <a long value>
floorNo = <an integer>
status = <CREATED/DRAFT>
I want my list of objects to be sorted such that they are ordered first by all DRAFT status, then by StorageZoneId and then by floorNo. What I have implemented till now does the final two steps, but how can I do the first one - basically split the list such that all "DRAFT" status are first followed by all "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;
}
}
答案1
得分: 2
使用Java 8或更高版本,您可以以另一种方式创建您的比较器:
// 将此代码放在某处,以便您不需要每次重新创建它
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);
(注意:由于我是凭记忆编写的,没有访问编译器,所以语法可能存在错误)
英文:
Using Java 8+ you could create your comparator in another way:
//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);
(Note: the syntax might contain error since I wrote this off the top of my head without having access to a compiler atm)
答案2
得分: 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") && o2.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。在第二次比较中情况相反。只有在两者的状态相同的情况下,才会考虑其他字段,继续使用你已经得到的方式。
英文:
I believe that something like so should do the trick:
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;
}
}
If the status of o1
is "DRAFT" and status of o2
is "CREATED" then o1
comes first for sure - return 1. In the second comparison the situation is reversed. Only if status of both is the same then other fields matter, we just continue with what you got so far.
答案3
得分: 1
以下是代码部分的中文翻译:
enum Status {
DRAFT, // 草稿
CREATED // 已创建
}
class MyObject {
long storageZoneId; // 存储区域ID
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);
}
}
请注意,我添加了相应的中文翻译注释。如果您有任何其他需要或疑问,请随时提出。
英文:
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);
}
}
Just to add to the other answer, you can use the Comparator builder to simplify the Comparator logic. The status field is defined as an enum, and enums are sorted based on the relative ordering in which the enum values appear in the enum definition. So your list will first be sorted based on DRAFT status as it appears first in the enum, and then CREATED status.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论