根据项目是否均匀对项目列表进行排序
Sorting a List of item based on whether they are even
所以我正在尝试根据汽车价格是否均匀来对 Car 对象列表进行排序。 SortEven 排序以便奇数浮到顶部但是我需要偶数浮到顶部。但对我来说,SortEven 的逻辑应该是交换,以便 evens 浮到顶部
有人可以解释 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 如果偶数则计算为 0。所以我检查第一个对象。如果 true t 保持位置,如果 false,c.getPrice() 将检查它是否为奇数,因为如果它是偶数,则将在第二次通过时进行检查。最后 return 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
}
然而这种排序使得奇数浮到顶部,与需要发生的事情相反
来自 Comparator 文档,
Compares its two arguments for order. Returns a negative integer,
zero, or a positive integer as the first argument is less than, equal
to, or greater than the second.
基本上,-1 和 1 不一定表示 swap/no-swap,它们只是表示小于或大于 then。分拣机将决定是否交换。
(问题最初在评论部分回答)。
所以我重构了一些我原来的解决方案,发现了一个逻辑缺陷,这可能是由于过度使用链式条件语句造成的。使用
我的条件语句中的 XOR 使事情变得更加清晰和易于阅读。
从一开始就应该做一个道理table
/*
* 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
}
}
所以我正在尝试根据汽车价格是否均匀来对 Car 对象列表进行排序。 SortEven 排序以便奇数浮到顶部但是我需要偶数浮到顶部。但对我来说,SortEven 的逻辑应该是交换,以便 evens 浮到顶部 有人可以解释 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 如果偶数则计算为 0。所以我检查第一个对象。如果 true t 保持位置,如果 false,c.getPrice() 将检查它是否为奇数,因为如果它是偶数,则将在第二次通过时进行检查。最后 return 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
}
然而这种排序使得奇数浮到顶部,与需要发生的事情相反
来自 Comparator 文档,
Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
基本上,-1 和 1 不一定表示 swap/no-swap,它们只是表示小于或大于 then。分拣机将决定是否交换。 (问题最初在评论部分回答)。
所以我重构了一些我原来的解决方案,发现了一个逻辑缺陷,这可能是由于过度使用链式条件语句造成的。使用 我的条件语句中的 XOR 使事情变得更加清晰和易于阅读。 从一开始就应该做一个道理table
/*
* 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
}
}