根据项目清单是否均匀排序

时间:2018-10-08 01:36:22

标签: java sorting comparator

因此,我试图根据汽车的价格是否均匀来对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
}

但是这种排序方式使奇数浮动到顶部,与发生的情况相反

2 个答案:

答案 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
    }

}