我试图使用接口比较器订购优先级队列,因此如果乘客有残疾,乘客的顺序取决于他们的残疾,那么取决于他们拥有的机票类型以及最后到达时间。
import java.util.*;
public static void main(String[] args){
Random rand = new Random(System.nanoTime());
Comparator<Passenger> comparator;
PriorityQueue<Passenger> queue = new PriorityQueue<Passenger>(10, comparator);
Passenger pass[] = new Passenger [10];
for (int i=0; i<10;i++){
int time1 = 0;
pass[i] = new Passenger(rand.nextInt(100000000), rand.nextInt(3) , rand.nextBoolean(), time1);
time1 = time1 + 15;
}
}
我初始化了乘客阵列,这里是乘客类和比较方法:
public class Passenger implements Comparator<Passenger>{
private int ID;
private int clase;
private boolean disability;
private int arrivalTime;
public Passenger(int ID, int clase, boolean disability, int arrivalTime) {
this.ID = ID;
this.clase = clase; // 0-vip 1-economy 2-economy
this.disability = disability;
this.arrivalTime = arrivalTime;
}
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public int getClase() {
return clase;
}
public void setClase(int clase) {
this.clase = clase;
}
public boolean isDisability() {
return disability;
}
public void setDisability(boolean disability) {
this.disability = disability;
}
public int getArrivalTime() {
return arrivalTime;
}
public void setArrivalTime(int arrivalTime) {
this.arrivalTime = arrivalTime;
}
public int compare(Passenger pas1, Passenger pas2) {
if((pas1.isDisability()) && (!pas2.isDisability())){
return 1; //passenger 1 has disability
}else if((!pas1.isDisability()) && (pas2.isDisability())){
return -1; //passenger 2 has disability
}
else{ //both have disability or no one has disability
if(pas1.getClase() < pas2.getClase()){
return 1; // passenger 1 has better class
}else if(pas1.getClase() > pas2.getClase()){
return -1; // passenger 2 has better class
}
else{ //both have disability and same class
if(pas1.getArrivalTime() < pas2.getArrivalTime()){
return 1; //passenger 1 arrived before passenger 2
}
else return -1; //passenger 2 arrived before passenger 1
}
}
}
如何以更好的方式处理这些多级比较?
答案 0 :(得分:1)
我认为您正在寻找的是重构代码,我建议将compare
逻辑分离到单独的PassengerComparator
类(SRP),以便更好地维护和可读性,如下所示。
public class PassengerComparator implements Comparator<Passenger> {
public int compare(Passenger pas1, Passenger pas2) {
//check the comparison of all
if(disabilityComparator(Passenger pas1, Passenger pas2)
&& arrivalTimeComparator(Passenger pas1, Passenger pas2)
&& claseComparator(Passenger pas1, Passenger pas2)) {
return 1;
} else {
return -1;
}
}
//compares only disability
private int disabilityComparator(Passenger pas1, Passenger pas2) {
return pas1.isDisability() - pas2.isDisability();
}
//compares only arrivalTime
private int arrivalTimeComparator(Passenger pas1, Passenger pas2) {
return pas1.getArrivalTime() - pas2.getArrivalTime();
}
//compares only clase
private int claseComparator(Passenger pas1, Passenger pas2) {
return pas1.getClase() - pas2.getClase();
}
}
<强>用法:强>
PriorityQueue<Book> queue = new PriorityQueue<Book>(10, new PassengerComparator());
答案 1 :(得分:0)
似乎您的问题是简化比较,但我认为您宁愿实施Comparable<Passenger>
而不是Comparator
,并使用#compareTo
方法。至于清理,如果你只是抽象实际的布尔逻辑,那也有点容易:
public int compareTo(Passenger other) {
if (this.isDisability() ^ other.isDisability()) { //use an XOR
return this.isDisability() ? 1 : -1; //1 for us, -1 for other
}
//compare #getClase
int clase = -Integer.compare(this.getClase(), other.getClase()); //invert
if (clase == 0) {
//compare arrival times if clase is equal
//normalize to -1, 1 (0 excluded in OP)
return this.getArrivalTime() < other.getArrivalTime() ? 1 : -1;
}
return clase > 0 ? 1 : -1; //normalize to -1, 0, 1
}
这允许您为Passenger
定义自然排序,并在您的类实现中封装/内部(不需要尽可能多的曝光)。
这也使排序操作变得更加容易:
List<Passenger> passengers = /* some list */;
Collections.sort(passengers);
如果你想提供一个可以完成替代排序的比较器,你也可以在课堂上做到这一点:
public class Passenger {
//...
public static class ArrivalComparator implements Comparator<Passenger> {
public int compare(Passenger one, Passenger two) {
return Integer.compare(one.getArrivalTime(), two.getArrivalTime());
}
}
//...
}
使用我们之前的示例,您可以根据到达时间对所有乘客进行排序:
Collections.sort(passengers, new Passenger.ArrivalComparator());
此外,这可以使用Java 8进行内联:
//Sort by arrival time
Collections.sort(passengers, (one, two) -> Integer.compare(one.getArrivalTime(), two.getArrivalTime());
但总的来说,请记住,比较器主要用于定义特定的排序,而Comparable
定义一般/自然排序。
答案 2 :(得分:0)
如何以更好的方式处理这些多级比较?
所以知道你有可重用的代码,允许你按照你想要的任何顺序进行排序,而无需编写复杂的多级比较器。
您可能还想查看Bean Comparator,这样可以轻松地在一行代码中创建单独的比较器。
答案 3 :(得分:0)
嘿,我只是得到了正确的答案,只需将其添加到班级乘客,它按照我想要的方式计算出来,所以偏好顺序是:残疾,班级和到达时间,非常感谢你。 :)
public int compareTo(Passenger other) {
if (this.isDisability() ^ other.isDisability()) { // use an XOR so it only enters if one of them is true
return this.isDisability() ? -1 : 1;
}
int clase = -Integer.compare(this.getClase(), other.getClase());
if (clase == 0) {
return this.getArrivalTime() < other.getArrivalTime() ? -1 : 1;
}
return clase > 0 ? -1 : 1;
}