使用比较器按预定义的优先顺序排序
Sort by predefined priority order using comparator
我有以下问题需要解决。我正在使用 Java.
餐厅识别 3 种类型的顾客:“NEWBIES”、“REGULARS”和“VIPs”。当客户下订单时,所有订单都加入队列。然而,订单始终以 VIP 服务于常客之前服务的方式提供,常客服务于新手之前。
我需要一个 class 可以用来对客户订单进行排序。如果两个客户属于同一类型,则应使用orderID对其进行排序。
如何使用比较器根据客户类型按订单优先级排序?
假设我已经有以下class订单
public class Order
{
public static int orderID;
private int tableNumber;
private String[] orderDetails;
private String customerType;
public Order(int tableNumber, String[] orderDetails, String customerType)
{
this.tableNumber = tableNumber;
this.orderDetails = orderDetails;
this.customerType = customerType;
orderID += 1;
}
// get and set methods declared
}
我已经实现了比较器如下:
import java.util.Comparator;
public class OrderComparator implements Comparator<Order>
{
@Override
public int compare(Order o1, Order o2)
{
if(o1.getType().equals(o2.getType()))
return o1.getOrderID - o2.getOrderID;
else
// How does comparing the customer type text ensure that
// it will be printed in the right order?
return o1.getType().compareTo(o2.getType());
}
}
你可以阅读这个问题How to sort a collection by multiple fields。特别是第二个答案,列出第一个选项。
您不仅想要 sort on multiple fields,还想要使用其中一个字段进行自定义排序。
在下面的代码中,我填写了 class Order
和 class OrderComparator
的缺失部分。代码后的注释。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Order {
public static final String NEWBIES = "NEWBIES";
public static final String REGULARS = "REGULARS";
public static final String VIP = "VIP";
private static int orderId;
private int orderID;
private int tableNumber;
private String[] orderDetails;
private String customerType;
public Order(int tableNumber, String[] orderDetails, String customerType) {
this.tableNumber = tableNumber;
this.orderDetails = orderDetails;
this.customerType = customerType;
orderID = ++orderId;
}
public int getOrderID() {
return orderID;
}
public int getTableNumber() {
return tableNumber;
}
public String[] getOrderDetails() {
return orderDetails;
}
public String getType() {
return customerType;
}
public String toString() {
return String.format("%d %s", orderID, customerType);
}
public static void main(String[] args) {
Order order1 = new Order(0, null, VIP);
Order order2 = new Order(0, null, REGULARS);
Order order3 = new Order(0, null, REGULARS);
List<Order> list = new ArrayList<>();
list.add(order3);
list.add(order2);
list.add(order1);
System.out.println("Unordered: " + list);
Collections.sort(list, new OrderComparator());
System.out.println("Ordered: " + list);
}
}
class OrderComparator implements Comparator<Order> {
@Override
public int compare(Order o1, Order o2) {
if (o1.getType().equals(o2.getType())) {
return o1.getOrderID() - o2.getOrderID();
}
else {
if (Order.VIP.equals(o1.getType())) {
return -1;
}
else if (Order.VIP.equals(o2.getType())) {
return 1;
}
else if (Order.REGULARS.equals(o1.getType())) {
return -1;
}
else if (Order.REGULARS.equals(o2.getType())) {
return 1;
}
else if (Order.NEWBIES.equals(o1.getType())) {
return -1;
}
else if (Order.NEWBIES.equals(o2.getType())) {
return 1;
}
throw new RuntimeException("Unexpected customer type.");
}
}
}
- 我将方法
main
添加到 class Order
以测试代码。
- 我将方法
toString
添加到 class Order
以便能够检查代码是否产生了预期的结果。
- 我知道您想要一种用于
Order
对象的分子。因此,我将成员 orderID
设为实例成员,因为每个 Order
都有自己的 ID,并且我添加了一个新的静态成员 orderId
(请注意 Java 区分大小写),这会产生一个每个新 Order
对象的新的唯一订单 ID。
- 您希望 VIP 订单在 REGULARS 订单之前出现,并且您希望 REGULARS 订单在 NEWBIES 订单之前出现。默认情况下,
Comparator
按升序排序,因此您希望 VIP 最低,NEWBIES 最高(纯粹为了排序目的)。所以在方法 compare
(属于 class OrderComparator
)中,如果 o1
的类型是 VIP 而 o2
的类型是 REGULARS 那么你希望 VIP 低于 REGULAR。因此在那种情况下,方法 compare
returns -1(减一).
运行 上面的代码产生以下输出。
Unordered: [3 REGULARS, 2 REGULARS, 1 VIP]
Ordered: [1 VIP, 2 REGULARS, 3 REGULARS]
请注意,由于 customerType
(在 class Order
中)是一个 String
,因此有可能创建一个 Order
对象无效的 customerType
值。您可以更改 class Order
的构造函数并添加对提供的值(对于 customerType
)的检查,如果提供的值无效则抛出 Exception
。或者您可以使用 enum (also known as enumerated types)。下面的代码使用 enum
而不是 String
作为 customerType
- 这也简化了方法 compare
in class OrderComparator
.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Order {
private static int orderId;
private int orderID;
private int tableNumber;
private String[] orderDetails;
private CustomerType customerType;
public Order(int tableNumber, String[] orderDetails, CustomerType customerType) {
this.tableNumber = tableNumber;
this.orderDetails = orderDetails;
this.customerType = customerType;
orderID = ++orderId;
}
public int getOrderID() {
return orderID;
}
public int getTableNumber() {
return tableNumber;
}
public String[] getOrderDetails() {
return orderDetails;
}
public CustomerType getType() {
return customerType;
}
public String toString() {
return String.format("%d %s", orderID, customerType);
}
public static void main(String[] args) {
Order order1 = new Order(0, null, CustomerType.VIP);
Order order2 = new Order(0, null, CustomerType.REGULARS);
Order order3 = new Order(0, null, CustomerType.REGULARS);
List<Order> list = new ArrayList<>();
list.add(order3);
list.add(order2);
list.add(order1);
System.out.println("Unordered: " + list);
Collections.sort(list, new OrderComparator());
System.out.println("Ordered: " + list);
}
}
class OrderComparator implements Comparator<Order> {
@Override
public int compare(Order o1, Order o2) {
if (o1.getType().equals(o2.getType())) {
return o1.getOrderID() - o2.getOrderID();
}
else {
return o2.getType().ordinal() - o1.getType().ordinal();
}
}
}
enum CustomerType {
NEWBIES, REGULARS, VIP
}
我有以下问题需要解决。我正在使用 Java.
餐厅识别 3 种类型的顾客:“NEWBIES”、“REGULARS”和“VIPs”。当客户下订单时,所有订单都加入队列。然而,订单始终以 VIP 服务于常客之前服务的方式提供,常客服务于新手之前。
我需要一个 class 可以用来对客户订单进行排序。如果两个客户属于同一类型,则应使用orderID对其进行排序。
如何使用比较器根据客户类型按订单优先级排序?
假设我已经有以下class订单
public class Order
{
public static int orderID;
private int tableNumber;
private String[] orderDetails;
private String customerType;
public Order(int tableNumber, String[] orderDetails, String customerType)
{
this.tableNumber = tableNumber;
this.orderDetails = orderDetails;
this.customerType = customerType;
orderID += 1;
}
// get and set methods declared
}
我已经实现了比较器如下:
import java.util.Comparator;
public class OrderComparator implements Comparator<Order>
{
@Override
public int compare(Order o1, Order o2)
{
if(o1.getType().equals(o2.getType()))
return o1.getOrderID - o2.getOrderID;
else
// How does comparing the customer type text ensure that
// it will be printed in the right order?
return o1.getType().compareTo(o2.getType());
}
}
你可以阅读这个问题How to sort a collection by multiple fields。特别是第二个答案,列出第一个选项。
您不仅想要 sort on multiple fields,还想要使用其中一个字段进行自定义排序。
在下面的代码中,我填写了 class Order
和 class OrderComparator
的缺失部分。代码后的注释。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Order {
public static final String NEWBIES = "NEWBIES";
public static final String REGULARS = "REGULARS";
public static final String VIP = "VIP";
private static int orderId;
private int orderID;
private int tableNumber;
private String[] orderDetails;
private String customerType;
public Order(int tableNumber, String[] orderDetails, String customerType) {
this.tableNumber = tableNumber;
this.orderDetails = orderDetails;
this.customerType = customerType;
orderID = ++orderId;
}
public int getOrderID() {
return orderID;
}
public int getTableNumber() {
return tableNumber;
}
public String[] getOrderDetails() {
return orderDetails;
}
public String getType() {
return customerType;
}
public String toString() {
return String.format("%d %s", orderID, customerType);
}
public static void main(String[] args) {
Order order1 = new Order(0, null, VIP);
Order order2 = new Order(0, null, REGULARS);
Order order3 = new Order(0, null, REGULARS);
List<Order> list = new ArrayList<>();
list.add(order3);
list.add(order2);
list.add(order1);
System.out.println("Unordered: " + list);
Collections.sort(list, new OrderComparator());
System.out.println("Ordered: " + list);
}
}
class OrderComparator implements Comparator<Order> {
@Override
public int compare(Order o1, Order o2) {
if (o1.getType().equals(o2.getType())) {
return o1.getOrderID() - o2.getOrderID();
}
else {
if (Order.VIP.equals(o1.getType())) {
return -1;
}
else if (Order.VIP.equals(o2.getType())) {
return 1;
}
else if (Order.REGULARS.equals(o1.getType())) {
return -1;
}
else if (Order.REGULARS.equals(o2.getType())) {
return 1;
}
else if (Order.NEWBIES.equals(o1.getType())) {
return -1;
}
else if (Order.NEWBIES.equals(o2.getType())) {
return 1;
}
throw new RuntimeException("Unexpected customer type.");
}
}
}
- 我将方法
main
添加到 classOrder
以测试代码。 - 我将方法
toString
添加到 classOrder
以便能够检查代码是否产生了预期的结果。 - 我知道您想要一种用于
Order
对象的分子。因此,我将成员orderID
设为实例成员,因为每个Order
都有自己的 ID,并且我添加了一个新的静态成员orderId
(请注意 Java 区分大小写),这会产生一个每个新Order
对象的新的唯一订单 ID。 - 您希望 VIP 订单在 REGULARS 订单之前出现,并且您希望 REGULARS 订单在 NEWBIES 订单之前出现。默认情况下,
Comparator
按升序排序,因此您希望 VIP 最低,NEWBIES 最高(纯粹为了排序目的)。所以在方法compare
(属于 classOrderComparator
)中,如果o1
的类型是 VIP 而o2
的类型是 REGULARS 那么你希望 VIP 低于 REGULAR。因此在那种情况下,方法compare
returns -1(减一).
运行 上面的代码产生以下输出。
Unordered: [3 REGULARS, 2 REGULARS, 1 VIP]
Ordered: [1 VIP, 2 REGULARS, 3 REGULARS]
请注意,由于 customerType
(在 class Order
中)是一个 String
,因此有可能创建一个 Order
对象无效的 customerType
值。您可以更改 class Order
的构造函数并添加对提供的值(对于 customerType
)的检查,如果提供的值无效则抛出 Exception
。或者您可以使用 enum (also known as enumerated types)。下面的代码使用 enum
而不是 String
作为 customerType
- 这也简化了方法 compare
in class OrderComparator
.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Order {
private static int orderId;
private int orderID;
private int tableNumber;
private String[] orderDetails;
private CustomerType customerType;
public Order(int tableNumber, String[] orderDetails, CustomerType customerType) {
this.tableNumber = tableNumber;
this.orderDetails = orderDetails;
this.customerType = customerType;
orderID = ++orderId;
}
public int getOrderID() {
return orderID;
}
public int getTableNumber() {
return tableNumber;
}
public String[] getOrderDetails() {
return orderDetails;
}
public CustomerType getType() {
return customerType;
}
public String toString() {
return String.format("%d %s", orderID, customerType);
}
public static void main(String[] args) {
Order order1 = new Order(0, null, CustomerType.VIP);
Order order2 = new Order(0, null, CustomerType.REGULARS);
Order order3 = new Order(0, null, CustomerType.REGULARS);
List<Order> list = new ArrayList<>();
list.add(order3);
list.add(order2);
list.add(order1);
System.out.println("Unordered: " + list);
Collections.sort(list, new OrderComparator());
System.out.println("Ordered: " + list);
}
}
class OrderComparator implements Comparator<Order> {
@Override
public int compare(Order o1, Order o2) {
if (o1.getType().equals(o2.getType())) {
return o1.getOrderID() - o2.getOrderID();
}
else {
return o2.getType().ordinal() - o1.getType().ordinal();
}
}
}
enum CustomerType {
NEWBIES, REGULARS, VIP
}