根据项目是否均匀对项目列表进行排序

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
    }

}