Java 使用 compareTo 和 Collections.sort
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18754490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using compareTo and Collections.sort
提问by user2745043
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)
我有一个特许经营班级,其中包括所有者(特许经营权名称的所有者)、州(特许经营所在州的 2 个字符串)和销售额(当天的总销售额)
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
compareTo 基于状态 ASCENDING 和 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:
当我在没有Collections.sort
正确比较的情况下比较这些特许经营对象时,但是当我使用Collections.sort
这里的同类进行测试时,我得到如下输出:
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
GA, 670.0, Roddy White
GA, 560.0, Julio Jones
IN, 1270.5, Andrew Luck
IN, 950.0, TY 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?
我认为 .sort 默认比较字符串是状态仍然正确的原因,我的问题是我如何实现它以根据销售额进行比较?
回答by nachokk
You have to modify your compareTo
method. Cause you are returning after comparing the state. So you have to compare state but sales too.
你必须修改你的compareTo
方法。因为您在比较状态后返回。因此,您必须比较状态,但也必须比较销售额。
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;
}
回答by Braj Kishore
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.
在您的问题陈述中,您说“compareTo 基于状态 ASCENDING 和销售 DESCENDING”。基于此,您的结果是有效的。各州按升序排列,每个州的销售额按降序排列。在接下来的陈述中,您要说(应首先考虑特定统计数据的较低销售额)。所以基本上你有两个相互矛盾的要求。两者不能同时进行。
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.
换句话说,您是否希望您的程序执行其他操作,例如两者都应该升序或降序或其他顺序。如果是,那么您必须相应地修改您的 compareTo 方法。
回答by prms
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.
这是因为首先比较条件是根据状态进行比较。如果当前对象的状态不小,则只进行基于销售额的比较。根据您的代码,在状态中,您希望当前对象的状态小于比较状态,但是在销售额比较中,您希望当前对象的销售额大于比较对象。这就是为什么你会得到不同的结果。状态按升序比较,销售额按降序进行比较。这完全取决于您从 compareTo 函数返回的内容。
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
希望这段代码能帮到你。你可以在这里找到很好的解释
回答by Mehul Gupta
Comparable will give only one way of comparision. This can be done using Comparator interface.
Comparable 只会给出一种比较方式。这可以使用 Comparator 接口完成。
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());
}
}