我知道这里描述的Java(和一般)中的比较规则。
我有一个字符串数组列表。
每个字符串代表一个德州扑克手,忽略花色。
每个字符串正好有13个字符长。
每个字符串仅由总和为7的数字组成。
例如,“0100300200100”代表一手由一张3、三张6、两张9和一张皇后组成的扑克。< br >(在这种情况下,这手牌代表满堂红-六加九)。
我想根据扑克手的力量对这个列表进行排序。
我有以下java代码,它实现了比较器的比较方法。
final Comparator<String> COMBINATION_ORDER = new Comparator<String>() {
@Override
public int compare(String c1, String c2) {
if (c1.indexOf('4') != -1 || c2.indexOf('4') != -1) { // Four of a kind
if (c1.indexOf('4') == c2.indexOf('4')) {
for (int i = 12; i >= 0; i--) {
if (c1.charAt(i) != '0' && c1.charAt(i) != '4') {
if (c2.charAt(i) != '0' && c2.charAt(i) != '4') {
return 0;
}
return 1;
}
if (c2.charAt(i) != '0' && c2.charAt(i) != '4') {
return -1;
}
}
}
return c1.indexOf('4') - c2.indexOf('4');
}
int tripleCount1 = StringFunctions.countOccurrencesOf(c1, "3");
int tripleCount2 = StringFunctions.countOccurrencesOf(c2, "3");
if (tripleCount1 > 1 || (tripleCount1 == 1 && c1.indexOf('2') != -1) || tripleCount2 > 1 || (tripleCount2 == 1 && c2.indexOf('2') != -1)) { // Full house
int higherTriple = c1.lastIndexOf('3');
if (higherTriple == c2.lastIndexOf('3')) {
for (int i = 12; i >= 0; i--) {
if (i == higherTriple) {
continue;
}
if (c1.charAt(i) == '2' || c1.charAt(i) == '3') {
if (c2.charAt(i) == '2' || c2.charAt(i) == '3') {
return 0;
}
return 1;
}
if (c2.charAt(i) == '2' || c2.charAt(i) == '3') {
return -1;
}
}
}
return higherTriple - c2.lastIndexOf('3');
}
return 0;
}
};
与此同时,我只提到四人组和满屋子。这意味着其他每手牌都将被视为彼此平等(但不如四人或满屋)。
但是当我分类的时候:
combinations.sort(COMBINATION_ORDER);
(其中组合是我的ArrayList)。
我得到一个例外。
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:773)
at java.util.TimSort.mergeAt(TimSort.java:510)
at java.util.TimSort.mergeCollapse(TimSort.java:437)
at java.util.TimSort.sort(TimSort.java:241)
at java.util.Arrays.sort(Arrays.java:1512)
at java.util.ArrayList.sort(ArrayList.java:1454)
at Poker.main(Poker.java:120)
请帮助我理解代码有什么问题。< br >非常感谢。
编辑:
正如@ajb所说,我没有考虑到没有满屋的“三分之一”。
解决方案:
final Comparator<String> COMBINATION_ORDER = new Comparator<String>() {
@Override
public int compare(String c1, String c2) {
if (c1.indexOf('4') != -1 || c2.indexOf('4') != -1) { // Four of a kind
if (c1.indexOf('4') == c2.indexOf('4')) {
for (int i = 12; i >= 0; i--) {
if (c1.charAt(i) != '0' && c1.charAt(i) != '4') {
if (c2.charAt(i) != '0' && c2.charAt(i) != '4') {
return 0;
}
return 1;
}
if (c2.charAt(i) != '0' && c2.charAt(i) != '4') {
return -1;
}
}
}
return c1.indexOf('4') - c2.indexOf('4');
}
int tripleCount1 = StringFunctions.countOccurrencesOf(c1, "3");
int tripleCount2 = StringFunctions.countOccurrencesOf(c2, "3");
if (tripleCount1 > 1 || (tripleCount1 == 1 && c1.indexOf('2') != -1)) { // c1 Full house
if (tripleCount2 > 1 || (tripleCount2 == 1 && c2.indexOf('2') != -1)) { // c2 Full house too
int higherTriple = c1.lastIndexOf('3');
if (higherTriple == c2.lastIndexOf('3')) {
for (int i = 12; i >= 0; i--) {
if (i == higherTriple) {
continue;
}
if (c1.charAt(i) == '2' || c1.charAt(i) == '3') {
if (c2.charAt(i) == '2' || c2.charAt(i) == '3') {
return 0;
}
return 1; // only c1 Full house
}
if (c2.charAt(i) == '2' || c2.charAt(i) == '3') { // only c2 Full house
return -1;
}
}
}
return higherTriple - c2.lastIndexOf('3');
}
return 1;
}
if (tripleCount2 > 1 || (tripleCount2 == 1 && c2.indexOf('2') != -1)) {
return -1;
}
return 0;
}
};
比较器必须遵守的条件之一是它必须是可传递的。也就是说,如果A
您的算法中至少存在一个逻辑错误。(可能还有其他错误,但我绝对可以发现这个错误,它绝对会导致异常。问题是当一只手有一个完整的房子,而另一只手有 3 个类型但不是完整的房子时。你的代码并不总是让整个房子变得更好。如果 3 张牌比满屋中的三张牌高出三张牌,那么 3 张牌的比较会更大。所以假设一只手是KKK8743,另一只手是QQQ6632,另一只手是JJJ8743。您的代码错误地使 KKK8743
我制作了一个带有jPanel和JLabel数组的调色板。起初它运行良好,但后来我从 JPanel 中取出了一些其他 jLabels,并添加了一些事件。现在我不断收到此错误: 我试图删除第一次收到此错误后所做的一切,但仍然不断收到它。当我将布局从 GridLayout 更改为其他任何内容时,错误消失了,但代码变得无用。所以我需要网格布局。当我将该 JPanel 中的所有内容移动到另一个 JPanel
有人能解释一下为什么我下面的比较器有时候会抛出上面的异常吗? 注意:myObject 中的 id 字段类型为 long。 解决方案: 基于@amit的回答
偏离变量只是包含以下字段的对象的一个实例: 附言时间对象是来自 Joda-Time 库的 DateTime 实例,TransportType 是包含常量火车、海船、驳船和卡车的枚举。 编辑: 好的,所以我将比较器编辑为以下内容: 但这显然违反了一般契约。我如何让它按时间排序,然后根据它们的其他属性对那些具有相等时间的对象进行排序,只关心它们是否相等?希望这有意义… 编辑:解决方案 谢谢大家回答我的
我有时会得到一个 for 我可以始终如一地抛出此异常,实时数据运行足够长的时间,但我不确定如何解决问题的实际原因。 我的比较仪有什么问题?(具体来说,我违反了合同的哪一部分?)如何在不掩盖异常的情况下修复它? 我使用的是 Java 7,如果不进行重大重写就无法升级。 我可以通过将设置为来掩盖异常,但这不是一个理想的解决方案。 我尝试创建测试来随机生成数据并验证每个合同条件。我无法抛出异常。 我尝试
我在整理名单 排序代码: FinalSentence类标头: compareTo()实现: 这是例外: 对于一个小列表(少于 50 个元素),它可以工作。对于一个大型列表(它也应该与那些一起使用),它会引发此异常。列表的实例类型是 ArrayList,这并不重要。 我不知道如何深入了解这一点。列表已满,元素类型相同(那里没有多态性),但是对于大型列表,我得到了这个奇怪的例外。 有什么想法吗? 谢谢
我有一个自己的,相对复杂的字符串比较器和一个庞大的字符串列表(~100个字符串,已经尝试减少,但问题不可重现),其中对它们进行排序会产生上述错误尝试使用Java 7排序。我想,规则 可能会被侵犯。找出违反合同的样品的最好方法是什么?