我正在尝试使用Collections.sort()对列表进行排序,并注意到正在对所有成员进行排序:
这是我的输入,打印出.compareTo()内部和输出:
5 4 3 2 1 // Original
me = 4: o = 5 // A printout at each entry into .compareTo()
me = 3: o = 4
me = 3: o = 5
me = 2: o = 5
me = 2: o = 3
me = 1: o = 3
me = 1: o = 2
4 5 3 2 1 // Final output (1 should be at the beginning though)
我的排序规则是:
1<4
3<2
4<5
我的实施是:
List<Task> tasks = new TaskList();
Task.create(tasks); // creates a list 5 4 3 2 1
while (scan.hasNext()) {
String line = scan.next();
Task.rules.add(line); // address the rules such as "1<4"
}
System.out.println(tasks);
Collections.sort(tasks);
compareTo()实现:
@Override
public int compareTo(Object arg0) {
int me = id;
int o = ((Task) arg0).id;
System.out.println("me = " + me + ": o = " + o);
for (String s : rules) { // rules is an array of strings "1<4" etc
int left = Integer.valueOf(s.substring(0, 1));
int right = Integer.valueOf(s.substring(2));
char op = s.charAt(1);
boolean meLeft = left == me;
boolean oLeft = left == o;
boolean meRight = right == me;
boolean oRight = right == o;
if (meLeft && oRight) {
if (op == '<') { // me < other
return -1;
} else
return 1;
} else if (oLeft && meRight) {
if (op == '<') {// other < me
return 1;
} else {
return -1;
}
}
}
return 0;
}
正如您从&#34; me = M,o = O&#34;在顶部,Collections.sort()没有遍历列表的所有成员!
我希望每位会员能够展示以下内容&#34; me&#34;所有其他成员&#34; o&#34;为了进行比较,我希望这个问题顶部的列表要长得多!我相信它的大小应该是N ^ 2 ......
答案 0 :(得分:2)
您的compareTo
方法会以两种方式破坏该方法的合约。
1)及物性表示如果x.compareTo(y) > 0
和y.compareTo(z) > 0
则x.compareTo(z) > 0
。您的方法会因为5 > 4
和4 > 1
而导致此问题中断,但5>1
不是您的规则之一。
2)compareTo
还必须符合x.compareTo(y) == 0
然后sgn(x.compareTo(z)) == sgn(y.compareTo(z))
所有z
的条件。您的方法会因为5.compareTo(1) == 0
而导致此错误,而5.compareTo(4)
和1.compareTo(4)
的符号相反。
如果您未达到compareTo
的合同,sort
的结果将无法预测。但是在你的情况下,我们可以看到发生了什么。因为4 < 5 = 3 < 2 = 1
,所以按顺序排列4,5,3,2,1 。 (我使用=
表示compareTo
方法返回0)。该链中没有>
个符号,因此没有理由继续排序。
如果您希望1来到前面,除了使compareTo
方法符合上述两个条件之外,您还必须添加至少一个涉及[1,4,5]和[1,4,5]的内容的规则来自[2,3]的东西。只要没有这样的规则,最终1没有理由超过2和3。