gpt4 book ai didi

java - 将 useLegacyMergesort 实现为 true 后,Collection.sort 在 JDK 8 中无法正确排序

转载 作者:行者123 更新时间:2023-12-01 18:04:28 28 4
gpt4 key购买 nike

我正在将一个项目从 JDK 7 升级到 JDK 8,最初我们遇到了一个异常:

java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.TimSort.mergeHi(Unknown Source) at java.util.TimSort.mergeAt(Unknown Source) at java.util.TimSort.mergeCollapse(Unknown Source) at java.util.TimSort.sort(Unknown Source) at java.util.Arrays.sort(Unknown Source) at java.util.ArrayList.sort(Unknown Source) at java.util.Collections.sort(Unknown Source)

我们通过使用java.util.Arrays.useLegacyMergeSort的系统属性作为true来解决这个问题。之后异常得到解决,但它执行的排序是错误的(排序不正确)。

注意:在 JDK 7 中,相同的代码可以完美运行(没有此系统属性)

public class SortTableModelRowComparator implements Comparator<TableModelSortingRow>
{
private boolean ascending = true;
protected int[] sortingColumns;

/**
* Constructor
*
*/
public SortTableModelRowComparator(boolean pSortAscendending, int[] pSortingColumns)
{
ascending=pSortAscendending;
sortingColumns=pSortingColumns;
}

@Override
public int compare(TableModelSortingRow o1,
TableModelSortingRow o2) {
BigDecimal firstvalue=(BigDecimal)o1.getValue(7);
BigDecimal secondvalue=(BigDecimal)o2.getValue(7);

return firstvalue.compareTo(secondvalue);
}
}

最佳答案

这就是使用该标志的问题。

原来的异常是指你的Comparator有问题或Comparable的比较运算。它的某些内容违反了 Comparable有效比较需要遵守的契约1。本质上,这是您的应用程序中的一个错误。

当您设置该标志时,您就是在告诉 JVM 忽略该问题。在某些情况下,您可以逃脱惩罚。在其他情况下......比如你的......后果将是不正确的。

解决方案:找出出现异常的原因,并解决该问题。

请注意,这可能是比较本身的问题,也可能是在对对象进行排序时发生了某些变化,这就是导致违反契约(Contract)的原因。

<小时/>

Note: In JDK 7 same code work perfectly(without this System properties)

Java 7 和 Java 8 中使用的排序算法不同2。但是,您很可能在 Java 7 中得到了不正确的排序,而您却没有注意到。

<小时/>

1 - Comparator contract如下:

“在前面的描述中,符号sgn(expression)表示数学符号函数,它被定义为根据表达式的值是负数、零还是正数返回-1、0或1之一.

  • 实现者必须确保 sgn(compare(x, y)) == -sgn(compare(y, x))对于所有人xy 。 (这意味着 compare(x, y) 必须抛出异常当且仅当 compare(y, x) 抛出异常。)

  • 实现者还必须确保关系是可传递的:((compare(x, y)>0) && (compare(y, z)>0))意味着compare(x, z)>0 .

  • 最后,实现者必须确保 compare(x, y)==0意味着sgn(compare(x, z))==sgn(compare(y, z))对于所有人z

2 - 此外,在 Java 7 中,算法的实现不会检查比较操作中的不正确行为。这解释了为什么在 Java 7 中没有异常(exception)。

关于java - 将 useLegacyMergesort 实现为 true 后,Collection.sort 在 JDK 8 中无法正确排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37805639/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com