Using compareTo and Collections.sort

五迷三道 提交于 2019-11-30 18:33:50

问题


I have a franchise class with owner(owner of franchise's name), state(2-character string for the state where the franchise is located), and sales (total sales for the day)

public class Franchise implements Comparable <Franchise>  {
final String owner;
final String state;
final double sales;

protected Franchise(String owner, String state, double sales ) {
    this.owner = owner;
    this.state = state;
    this.sales = sales;
}
public String toString() {
    String str = state + ", " + sales + ", " + owner;
    return str;
}
public String getState() {
    return state;
}
public double getSales() {
    return sales;
}
public int compareTo(Franchise that) {
    double thatSales = that.getSales();
    if (this.getState().compareTo(that.getState()) < 0)  
        return -1;
    else if (this.getSales() > thatSales)
        return -1;
    else if (this.getSales() < thatSales)
            return 1;
    else
        return 0;
}
}

the compareTo is based on state ASCENDING and sales DESCENDING

import java.util.ArrayList;
import java.util.Collections;

public class FranchiseTester {

public static void main(String[] args) {
    ArrayList<Franchise> franchises = new ArrayList<Franchise>();
    Franchise a = new Franchise("Andrew Luck", "IN", 1270.5);
    Franchise b = new Franchise("Ray Rice", "MD", 1210);
    Franchise c = new Franchise("Alfred Morris", "WA", 980.5);
    Franchise d = new Franchise("Roddy White", "GA", 670);
    Franchise e = new Franchise("Greg Olsen", "SC", 740);
    Franchise f = new Franchise("T.Y. Hilton", "IN", 950);
    Franchise g = new Franchise("Julio Jones", "GA", 560);

    franchises.add(a);
    franchises.add(b);
    franchises.add(c);
    franchises.add(d);
    franchises.add(e);
    franchises.add(f);
    franchises.add(g);

    Collections.sort(franchises);

    for(int i = 0; i < franchises.size(); i++) {   
        System.out.print(franchises.get(i) + "\n");
    } 
}

}

when I compare these franchise objects without the Collections.sort they compare correctly, However when I test using the Collections.sort like I have here I get an output like this:

GA, 670.0, Roddy White
GA, 560.0, Julio Jones
IN, 1270.5, Andrew Luck
IN, 950.0, T.Y. Hilton
MD, 1210.0, Ray Rice
SC, 740.0, Greg Olsen
WA, 980.5, Alfred Morris

The state's are still being compared correctly but it's not comparing by sales properly (lower sales for particular stat should come first)

I think that the .sort compares string by default is the reason that states are still correct, my question is how do I implement it to compare based on sales too?


回答1:


In your problem statement you are saying that "compareTo is based on state ASCENDING and sales DESCENDING". Based on this your results are valid. States are in ascending order and for each state the sale is in descending order. In the very next statement you are saying (lower sales for particular stat should come first). So basically you have two conflicting requirement. Both can not be done simultaneously.

In other words do you want your program to do something else like both should be ascending or both descending or some other order. If yes then you have to modify your compareTo method accordingly.




回答2:


You have to modify your compareTo method. Cause you are returning after comparing the state. So you have to compare state but sales too.

For example:

public int compareTo(Franchise that) {
    int stateComparition = this.getState().compareTo(that.getState()); 
    Double sales = Double.valueOf(this.getSales());    
    Double thatSales = Double.valueOf(that.getSales());
    int salesComparition = sales.compareTo(thatSales);    

    if(stateComparition == 0){
        if(salesComparition > 0)
             return -1;
        else if(salesComparition < 0)
             return 1;
        else
             return 0;
    }
       return stateComparition;         
}



回答3:


It is because at first comparision condition you are comparing on the basis of state. If the state of current object is not small, then only comparision based on sales will take place. According to your code, in state you want the state of current object to be less than the comparing state, however in sales comparision you want the sales of current object to be greater than the comparing object. This is why you are getting different results. States are being compared in ascending order and sales in descending order. It is all dependent on what you return from compareTo function.

public int compareTo(Franchise that) {
double thatSales = that.getSales();
if (this.getState().compareTo(that.getState()) < 0)  
    return -1;
else if (this.getSales() < thatSales)
    return -1;
else if (this.getSales() > thatSales)
        return 1;
else
    return 0;
}

Hope this code will help you. You can find good explanation over here




回答4:


Comparable will give only one way of comparision. This can be done using Comparator interface.

Collections.sort(list, new Comparator<Franchise>() {
@Override
            public int compare(Franchise obj1, Franchise obj2) {
                if(obj1.getState().compareTo(obj2.getState()) == 0)
                {
                    Double a1 =obj1.getSales();
                    Double a2 = obj2.getSales();
                    return a2.compareTo(a1);
                }

                    return o1.getName().compareTo(o2.getName());
        } 
}


来源:https://stackoverflow.com/questions/18754490/using-compareto-and-collections-sort

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!