因此,我试图根据汽车的价格是否均匀来对Car对象列表进行排序。 SortEven进行排序,以使奇数浮到顶部,但是我需要偶数浮到顶部。但对我来说,SortEven的逻辑应该交换,以便偶数浮动到顶部 有人可以解释SortEven的工作方式吗?
package Consumables;
import java.util.Comparator;
public class Cars implements Comparable<Cars>{
private String registrationNumber;
private int price;
private int seats;
private int mpg;
public static final Comparator<Cars> BY_MPG = new ByMPG();
public static final Comparator<Cars> BY_SEATS = new BySeats();
public static final Comparator<Cars> SORT_EVEN = new SortEven();
public Cars(String regNumber) {
this.setRegistrationNumber(regNumber);
}
private static class ByMPG implements Comparator<Cars> {
public int compare(Cars t, Cars c) {
return t.getMpg() - c.getMpg();
}
}
private static class BySeats implements Comparator<Cars> {
public int compare(Cars t, Cars c) {
return t.getSeats() - c.getSeats();
}
}
我想做的事情/逻辑:t.getPrice()%2评估为偶数。所以我检查第一个对象。如果为true,则t保留位置;如果为false,则检查c.getPrice()是否为奇数,因为如果为偶数,则将在第二遍检查。最终返回0。
private static class SortEven implements Comparator<Cars> {
public int compare(Cars t, Cars c) {
if ((t.getPrice() % 2) == 0)
return 1;
else if ((c.getPrice() % 2) != 0)
return -1;
return 0;
}
}
public String getRegistrationNumber() {
return registrationNumber;
}
public void setRegistrationNumber(String registrationNumber) {
this.registrationNumber = registrationNumber;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getSeats() {
return seats;
}
public void setSeats(int seats) {
this.seats = seats;
}
public int getMpg() {
return mpg;
}
public void setMpg(int mpg) {
this.mpg = mpg;
}
@Override
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if (obj != null && obj instanceof Cars) {
String regNumber = ((Cars)obj).getRegistrationNumber();
if (regNumber != null && regNumber.equals(this.registrationNumber))
return true;
}
return false;
}
@Override
public int hashCode() {
return this.registrationNumber.hashCode();
}
@Override
public int compareTo(Cars o) {
// TODO Auto-generated method stub
if (o != null && o instanceof Cars) {
if (this.getPrice() > o.getPrice())
return 1;
else if (this.getPrice() < o.getPrice())
return -1;
}
return 0;
}
@Override
public String toString() {
return "Registration Number: " + this.getRegistrationNumber()
+ "\n Price: " + this.getPrice()
+ "\n # of Seats : " + this.getSeats()
+ "\n MPG : " + this.getMpg();
}
}
随机生成值
import Consumables.Cars;
/**
* @author briensmarandache
*
*/
public class ComparatorSketchpad {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Cars> listOfCars = new ArrayList<>();
for (int i=0; i < 100; i++) {
Cars car = new Cars("H0-" + i);
car.setMpg((int)(Math.random() * ((40 - 20) + 1)) + 20);
car.setSeats((int)(Math.random() * ((8 - 2) + 1)) + 2);
car.setPrice((int)(Math.random() * ((80_000 - 5_000) + 1)) + 5_000);
listOfCars.add(car);
}
Collections.sort(listOfCars, Cars.SORT_EVEN);
System.out.println("============ Print sorted by even price list ==========");
Iterator<Cars> carIteratorByEven = listOfCars.iterator();
while (carIteratorByEven.hasNext()) {
System.out.println(carIteratorByEven.next());
}
}
}
这可以解决问题,但是我无法理解其工作原理。似乎是向后操作
private static class SortEven implements Comparator<Cars> {
public int compare(Cars t, Cars c) {
if ((t.getPrice() % 2) == 0 && (c.getPrice() % 2) == 0)
return 0;
else if ((t.getPrice() % 2) == 0 || (c.getPrice() % 2) != 0)
return -1; // walk through debugger
return 1;
}
我有建议的更改(即使用&&和完整的案例比较).....
private static class SortEven implements Comparator<Cars> {
public int compare(Cars t, Cars c) {
if (((t.getPrice() % 2) == 0 && (c.getPrice() % 2) == 0) || (t.getPrice() % 2) != 0 && (c.getPrice() % 2) != 0 )
return 0; // no swap
else if ((t.getPrice() % 2) == 0 && (c.getPrice() % 2) != 0)
return 1; // no swap // walk through debugger
return -1; // swap
}
但是这种排序方式使奇数浮动到顶部,与发生的情况相反
答案 0 :(得分:0)
从Comparator文档中,
比较其两个参数的顺序。返回一个负整数, 零或正整数,因为第一个参数小于,等于 达到或大于秒。
基本上,-1和1不一定表示交换/不交换,它们的意思是小于或大于。分类器将决定是否交换。 (最初在评论部分回答的问题)。
答案 1 :(得分:0)
因此,我重构了一些原始的解决方案,发现了一个逻辑缺陷,它可能是由于过度使用链式条件语句引起的。使用 我的条件语句中的XOR使事情更清晰,更易于阅读。 从一开始就应该做一个真值表。
/*
* SortEven Logic custom sort method
* GIVEN:
* + odd ---> should shift right (heavy weight)
* + evens -> should shift left (light weight)
* + n modulo 2 of any number n should equate to zero
* as 2 divides n perfectly (w/o remainder)
*
* Cases: even-even, even-odd, odd-even, odd-odd
* odd-odd and even-even are equal ---> in that they are
* comparing 2 items that "weigh" the same. Thus, operations
* should be equal to each other. In context of sorting based off of whether
* even is t or c, the FIRST condition test whether even-even or odd-odd is present
* and return zero if true. *** REFER TO TRUTH TABLE IF FIRST CONDITION IS CONFUSING ***
* SECOND condition, we only need to check if (t)arget element is odd. *************
* *********************************************************************************
* MAY NEED TO CHANGE equals() TO MAINTAIN INTGRETY OF compareTo()
* *********************************************************************************
* THIRD condition, (t)arget is even
*
*
* Truth Table (even/odd = T/F) (t/c = A/B) (t = (t.getPrice() % 2 == 0)) (c = (c.getPrice() % 2 == 0))
*
* A | B | (A AND B) OR (!A AND !B) | !(A XOR B)
* T | T | T | T
* T | F | F | F
* F | T | F | F
* F | F | T | T
*
*
*/
private static class SortEven implements Comparator<Cars> {
public int compare(Cars t, Cars c) {
if ( !( ((t.getPrice() % 2) == 0) ^ ((c.getPrice() % 2) == 0)) ) // check if even-even or odd-odd
return 0;
else if ((t.getPrice() % 2) != 0) // check if first element is odd; if so
return 1; // heavy weight found
return -1; // light weight found
}
}