HCRM博客

TimSort使用中的常见报错如何解决?

TimSort是一种混合排序算法,由Tim Peters于2002年设计,并成为Python中list.sort()的默认实现,它结合了归并排序和插入排序的优点,以在真实世界中的各种数据上表现出较好的性能,在使用TimSort时,有时会遇到报错的情况,Comparison method violates its general contract!”,本文将详细解释TimSort报错的原因、解决方法以及相关FAQs。

TimSort报错的原因及解决方法

一、原因分析

TimSort使用中的常见报错如何解决?-图1
(图片来源网络,侵权删除)

1、比较方法违反了一般契约:TimSort要求比较方法必须满足以下三个特性:

自反性:x与y的比较结果和y与x的比较结果相反。

传递性:如果x > y且y > z,则x > z。

对称性:如果x = y,则x与任何z的比较结果和y与z的比较结果相同。

如果不满足这些特性,就会抛出“Comparison method violates its general contract!”异常,以下代码会导致该错误:

  • public int compareTo(OrgChartBean o) {
  • if (o == null || o.getCount() < getCount()) {
  • return 1;
  • }
  • return 1;
  • }

上述代码未处理o.getCount() == getCount()的情况,导致不满足对称性。

TimSort使用中的常见报错如何解决?-图2
(图片来源网络,侵权删除)

2、数组长度大于等于32时合并操作触发的错误:当数组长度较大时,TimSort会将数组分成多个run进行排序,然后合并这些run,如果合并过程中出现不符合预期的情况,也可能导致报错。

二、解决方法

1、修正比较方法:确保比较方法满足TimSort的三个特性,修正后的代码如下:

  • public int compareTo(OrgChartBean o) {
  • if (o == null || o.getCount() < getCount()) {
  • return 1;
  • } else if (o.getCount() > getCount()) {
  • return 1;
  • } else {
  • return 0;
  • }
  • }

2、使用旧版排序方法:如果不想修改比较方法,可以设置系统属性java.util.Arrays.useLegacyMergeSort为true,使用旧的排序方法(非TimSort),但这种方法不推荐,因为无法享受TimSort带来的性能优势。

  • System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");

示例代码及分析

以下是一个完整的示例代码,演示如何生成一个包含32个元素的随机数列表,并使用TimSort进行排序,如果比较方法不正确,将抛出异常。

  • import java.util.*;
  • public class TimSortExample {
  • public static void main(String[] args) {
  • List<OrgChartBean> resultList = new ArrayList<OrgChartBean>(32);
  • long[] a = new long[]{13, 14, 35, 11, 8, 33, 15, 29, 12, 0, 45, 20, 5, 37, 41, 9, 21, 7, 36, 6, 46, 22, 47, 32, 40, 5, 18, 27, 48, 16, 17, 23};
  • for (int i = 0; i < 32; i++) {
  • OrgChartBean bean = new OrgChartBean();
  • bean.setCount(a[i]);
  • resultList.add(bean);
  • }
  • String originalArr = resultList.toString();
  • try {
  • Collections.sort(resultList);
  • } catch (Exception e) {
  • System.out.println(resultList);
  • System.out.println(originalArr);
  • throw e;
  • }
  • }
  • }
  • class OrgChartBean implements Comparable<OrgChartBean>, Serializable {
  • private static final long serialVersionUID = 1L;
  • private long count;
  • public OrgChartBean() {
  • super();
  • }
  • public long getCount() {
  • return count;
  • }
  • public void setCount(long count) {
  • this.count = count;
  • }
  • @Override
  • public int compareTo(OrgChartBean o) {
  • if (o == null || o.getCount() < getCount()) {
  • return 1;
  • } else if (o.getCount() > getCount()) {
  • return 1;
  • } else {
  • return 0;
  • }
  • }
  • @Override
  • public String toString() {
  • return "" + count;
  • }
  • }

TimSort作为一种高效的排序算法,广泛应用于各种编程语言中,要正确使用TimSort,必须确保比较方法符合其要求的三个特性:自反性、传递性和对称性,如果遇到“Comparison method violates its general contract!”异常,通常是因为比较方法不符合这些特性,通过修正比较方法或使用旧版排序方法,可以解决这一问题,TimSort的设计初衷是为了在真实世界的数据中提供更好的性能,因此在实际应用中应尽量遵循其规则,以发挥其最大优势。

本站部分图片及内容来源网络,版权归原作者所有,转载目的为传递知识,不代表本站立场。若侵权或违规联系Email:zjx77377423@163.com 核实后第一时间删除。 转载请注明出处:https://blog.huochengrm.cn/gz/18869.html

分享:
扫描分享到社交APP
上一篇
下一篇