4 回答

TA貢獻1900條經(jīng)驗 獲得超5個贊
好吧,從 Java 8 開始,您可以像這樣構(gòu)建比較器:
//order by delivery date first, ascending order
Comparator<Car> carComparator = Comparator.comparing( Car::getDeliveryDate )
//order by isReady in ascending order
.thenComparing( Car::getIsReady )
//we map null to 1 and non-null to -1 and ignore the rest for now
.thenComparing( car -> car.getGear() != null ? -1 : 1 )
.thenComparing( car -> car.getTyre() != null ? -1 : 1 );

TA貢獻1848條經(jīng)驗 獲得超10個贊
檢查此比較器,以便您可以使用多個屬性進行排序
public class CarComparator implements Comparator<Car> {
@Override
public int compare(Car entry1, Car entry2) {
int value;
if (entry1.getDeliveryDate().before(entry2.getDeliveryDate())){
value = -1;
}else if (entry1.getDeliveryDate().equals(entry2.getDeliveryDate())){
value = 0;
}else{
value =1;
}
//For same day
if (value==0){
if (entry1.getIsReady() > entry2.getIsReady()) {
value = -1;
} else if (entry1.getIsReady() < entry2.getIsReady()) {
value = 1;
} else if (entry1.getIsReady() == entry2.getIsReady()) {
value = 0;
}
}
//if same isReady
if (value==0){
if (entry1.getGear()!=null && entry2.getGear()==null) {
value = -1;
} else if (entry1.getGear()==null && entry2.getGear()==null) {
value = 0;
} else{
value = 1;
}
}
//if still equals
if (value==0){
if (entry1.getTyre()!=null && entry2.getTyre()==null) {
value = -1;
} else if (entry1.getTyre()==null && entry2.getTyre()==null) {
value = 0;
} else{
value = 1;
}
}
return value;
}
}
我不確定這是否是您嘗試做的。上面的比較器的作用是:首先對日期進行排序,如果找到相等的日期(值=0),則比較 isReady,然后比較 getGear(),最后比較 getTyre()。
這樣您就可以在比較器中添加所需數(shù)量的屬性。
包括3輛車的主要方法
public class Main {
public static void main (String[]args) throws UnsupportedEncodingException, ParseException {
List<Car> carL = new ArrayList<Car>();
Car car1 = new Car();
car1.setDeliveryDate(new Date());
Gear gear1 = new Gear();
car1.setGear(gear1);
Tyre tyre1 = new Tyre();
car1.setTyre(null);
car1.setId(1);
car1.setDeliveryDate((new SimpleDateFormat("dd-MM-yyyy")).parse("01-01-2000"));
car1.setIsReady(0);
Car car2 = new Car();
car2.setDeliveryDate(new Date());
Gear gear2 = new Gear();
car2.setGear(gear2);
Tyre tyre2 = new Tyre();
car2.setTyre(tyre2);
car2.setId(2);
car2.setDeliveryDate((new SimpleDateFormat("dd-MM-yyyy")).parse("02-01-2000"));
car2.setIsReady(1);
Car car3 = new Car();
car3.setDeliveryDate(new Date());
Gear gear3 = new Gear();
car3.setGear(gear3);
Tyre tyre3 = new Tyre();
car3.setTyre(tyre3);
car3.setId(3);
car3.setDeliveryDate((new SimpleDateFormat("dd-MM-yyyy")).parse("01-01-2000"));
car3.setIsReady(1);
carL.add(car1);
carL.add(car2);
carL.add(car3);
Collections.sort(carL, new CarComparator());
for (Car car : carL) {
System.out.println("car: " + car.toString());
}
}
}
輸出:
car: Car{id=3, isReady=1, tyre=false, gear=false, deliveryDate=Sat Jan 01 00:00:00 EET 2000}
car: Car{id=1, isReady=0, tyre=true, gear=false, deliveryDate=Sat Jan 01 00:00:00 EET 2000}
car: Car{id=2, isReady=1, tyre=false, gear=false, deliveryDate=Sun Jan 02 00:00:00 EET 2000}

TA貢獻1818條經(jīng)驗 獲得超8個贊
為什么不重用 Integer.compareTo 來使代碼更短?
像這樣:
import java.util.Comparator;
public class CarComparator implements Comparator<Car> {
@Override
public int compare(Car entry1, Car entry2) {
int value = 0;
// might want to add a null check for either entry1 and entry2
value = entry1.getDeliveryDate().compareTo(entry2.getDeliveryDate());
if (value == 0) {
value = ((Integer)entry1.getIsReady()).compareTo((Integer)entry2.getIsReady());
if (value == 0) {
value = getIntegerValueForNullCheck(entry1.getGear()).compareTo(getIntegerValueForNullCheck(entry2.getGear()));
if (value == 0) {
value = getIntegerValueForNullCheck(entry1.getTyre()).compareTo(getIntegerValueForNullCheck(entry2.getTyre()));
}
}
}
return value;
}
private Integer getIntegerValueForNullCheck (Object o) {
return o == null ? 0 : 1;
}
}
包括測試排序的代碼:
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.*;
public class Sorting {
public static void main(String[] args) {
List<Car> cars = new LinkedList<>();
Date today = new Date();
Instant now = Instant.now();
Instant after = now.plus(Duration.ofDays(1));
Date tomorrow = Date.from(after);
cars.add(new Car(5, new Tyre(1,"1"), new Gear(1, "1"), today ));
cars.add(new Car(5, new Tyre(1,"1"), null, today ));
cars.add(new Car(5, null, null, today ));
cars.add(new Car(4, null, null, today ));
cars.add(new Car(3, null, null, tomorrow ));
Collections.sort(cars, new CarComparator());
System.out.println(cars);
}
}
輸出:
[Car{isReady=4, tyre=null, gear=null, deliveryDate=Thu Oct 10 11:27:20 IDT 2019}
, Car{isReady=5, tyre=null, gear=null, deliveryDate=Thu Oct 10 11:27:20 IDT 2019}
, Car{isReady=5, tyre=Tyre{id=1, grip='1'}, gear=null, deliveryDate=Thu Oct 10 11:27:20 IDT 2019}
, Car{isReady=5, tyre=Tyre{id=1, grip='1'}, gear=Gear{id=1, type='1'}, deliveryDate=Thu Oct 10 11:27:20 IDT 2019}
, Car{isReady=3, tyre=null, gear=null, deliveryDate=Fri Oct 11 11:27:20 IDT 2019}
]

TA貢獻1155條經(jīng)驗 獲得超0個贊
老實說,我沒有發(fā)現(xiàn)你的代碼有什么問題。也就是說,如果您的意圖是當(dāng)條目 1 大于條目 2 時返回 -1(與范數(shù)相反的順序)。如果沒有更多的代碼需要閱讀,我認為如果您嘗試比較為您的用例構(gòu)建的值更大或更小,您的代碼將會起作用。
但是,我認為您的返回方法效率較低。您不需要返回值。您可以只返回一個實際值。
為了進行比較,您可以先比較 ==,然后再評估其余的。但這可能很難閱讀代碼,所以我給你兩個版本。
刪除值版本:
public class CarComparator implements Comparator<Car> {
@Override
public int compare(Car entry1, Car entry2) {
if (entry1.getisReady() > entry2.getisReady()) {
return -1;
} else if (entry1.getisReady() < entry2.getisReady()) {
return 1;
} else if (entry1.getisReady() == entry2.getisReady()) {
return 0;
}
}
}
刪除值和不同風(fēng)格的比較:
public class CarComparator implements Comparator<Car> {
@Override
public int compare(Car entry1, Car entry2) {
if (entry1.getisReady() == entry2.getisReady()) return 0;
return entry1.getisReady() > entry2.getisReady()? -1 : 1;
}
}
我不確定我是否正確地理解了您的意思,但如果我沒有理解,我希望這段代碼可以幫助您。我將它們分為 3 個方法,希望您能獲得 getTyre() 和 getGear() 方法。您可以根據(jù)需要組合它們,對于最后一個方法,其值被分成變量順序以便于閱讀代碼。
class CarComparator implements Comparator<Car> {
public int compare(Car entry1, Car entry2) {
if (entry1.getisReady() == entry2.getisReady()) return 0;
return entry1.getisReady() > entry2.getisReady()? -1 : 1;
}
public int compareGear(Car entry1, Car entry2){
if ( (entry1.getGear() != null && entry2.getGear() != null)
||(entry1.getGear() == null && entry2.getGear() == null)
){
return compare(entry1, entry2);
}
return entry1.getGear() != null && entry2.getGear() == null? -1 : 1;
}
public int compareTye(Car entry1, Car entry2){
int order1 = entry1.getGear() != null && entry1.getTyre() != null? 1 : 0;
int order2 = entry2.getGear() != null && entry2.getTyre() != null? 1 : 0;
if ( order1 == order2 ) return compare(entry1, entry2);
return order1 > order2? -1 : 1;
}
}
添加回答
舉報