`
qxf567
  • 浏览: 21329 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java7排序

 
阅读更多

    在使用jdk1.7后发现,部分使用排序的列表变了。然后就可劲的找原因。最后发现:

 

首先进入Collection.sort方法

    public static <T extends Comparable<? super T>> void sort(List<T> list) {
        Object[] a = list.toArray();
        Arrays.sort(a);
        ListIterator<T> i = list.listIterator();
        for (int j=0; j<a.length; j++) {
            i.next();
            i.set((T)a[j]);
        }
    }

 本质就是对数组进行排序然后输出。

 

再进入Arrays.sort()方法

    public static void sort(Object[] a) {
        if (LegacyMergeSort.userRequested)
            legacyMergeSort(a);
        else
            ComparableTimSort.sort(a);
    }

 看到这,其实也里看到点东西了,哈哈userRequested,再点进去

    static final class LegacyMergeSort {
        private static final boolean userRequested =
            java.security.AccessController.doPrivileged(
                new sun.security.action.GetBooleanAction(
                    "java.util.Arrays.useLegacyMergeSort")).booleanValue();
    }

 原来如此,在JVM中配置-Djava.util.Arrays.useLegacyMergeSort=true ,就可以使用传统的归并排序了。

到此为止,已经解决为什么JDK1.7的排序会与JDK1.6不致的问题的。下面我们来深入的看下这两个排序方式的迥异:

legacyMergeSort()核心实现

    private static void mergeSort(Object[] src,
                                  Object[] dest,
                                  int low,
                                  int high,
                                  int off) {
        int length = high - low;

        // Insertion sort on smallest arrays
        if (length < INSERTIONSORT_THRESHOLD) {
            for (int i=low; i<high; i++)
                for (int j=i; j>low &&
                         ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
                    swap(dest, j, j-1);
            return;
        }

        // Recursively sort halves of dest into src
        int destLow  = low;
        int destHigh = high;
        low  += off;
        high += off;
        int mid = (low + high) >>> 1;
        mergeSort(dest, src, low, mid, -off);
        mergeSort(dest, src, mid, high, -off);

        // If list is already sorted, just copy from src to dest.  This is an
        // optimization that results in faster sorts for nearly ordered lists.
        if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
            System.arraycopy(src, low, dest, destLow, length);
            return;
        }

        // Merge sorted halves (now in src) into dest
        for(int i = destLow, p = low, q = mid; i < destHigh; i++) {
            if (q >= high || p < mid && ((Comparable)src[p]).compareTo(src[q])<=0)
                dest[i] = src[p++];
            else
                dest[i] = src[q++];
        }
    }

 排序个数小于7,直接使用插入排序,时间复杂度为O(n2),适用于小数据排序。其它部分典型的归并排序实现法。不过人家写的确实高效率 int mid = (low + high) >>> 1; 给我们肯定直接就成了int mid=(low+high)/2;

 

ComparableTimSort.sort(a)核心实现

        rangeCheck(a.length, lo, hi);
        int nRemaining  = hi - lo;
        if (nRemaining < 2)
            return;  // Arrays of size 0 and 1 are always sorted

        // If array is small, do a "mini-TimSort" with no merges
        if (nRemaining < MIN_MERGE) {
            int initRunLen = countRunAndMakeAscending(a, lo, hi);
            binarySort(a, lo, hi, lo + initRunLen);
            return;
        }

        /**
         * March over the array once, left to right, finding natural runs,
         * extending short natural runs to minRun elements, and merging runs
         * to maintain stack invariant.
         */
        ComparableTimSort ts = new ComparableTimSort(a);
        int minRun = minRunLength(nRemaining);
        do {
            // Identify next run
            int runLen = countRunAndMakeAscending(a, lo, hi);

            // If run is short, extend to min(minRun, nRemaining)
            if (runLen < minRun) {
                int force = nRemaining <= minRun ? nRemaining : minRun;
                binarySort(a, lo, lo + force, lo + runLen);
                runLen = force;
            }

            // Push run onto pending-run stack, and maybe merge
            ts.pushRun(lo, runLen);
            ts.mergeCollapse();

            // Advance to find next run
            lo += runLen;
            nRemaining -= runLen;
        } while (nRemaining != 0);

        // Merge all remaining runs to complete sort
        assert lo == hi;
        ts.mergeForceCollapse();
        assert ts.stackSize == 1;
    

 ComparableTimSort来源于GOOGLE,详见下文

 

 

两个对象直接比如定义Comparator

public double compare(Object o1, Object o2) {
		ComparaContainer tr1 = (ComparaContainer) o1;
		ComparaContainer tr2 = (ComparaContainer) o2;

		if (tr1.getCompareValue() < tr2.getCompareValue()) {
			return (tr1.getCompareValue()-tr2.getCompareValue());
		} else if (tr1.getCompareValue() == tr2.getCompareValue()) {
			return tr1.getSecondValue() <= tr2.getSecondValue() ? 0 : 1;
		} else {
			return 1;
		}
}

 

由于1.7改得更为严谨不能直接使用-1,0,1来表示小于、等于、大于

得改用a-b

 

如下所示

	public int compare(Object o1, Object o2) {
		ComparaContainer tr1 = (ComparaContainer) o1;
		ComparaContainer tr2 = (ComparaContainer) o2;
		double m = tr1.getCompareValue()-tr2.getCompareValue();
		if (tr1.getCompareValue() < tr2.getCompareValue()) {
			return (int)m;
		} else if (tr1.getCompareValue() == tr2.getCompareValue()) {
			m = tr1.getSecondValue()- tr2.getSecondValue();
			return (int)m;
		} else {
			return (int)m;
		}
	}

 

或者最简单的是将原来return 0;的改成return -1; 

 

 

分享到:
评论

相关推荐

    java中文排序,数字字母汉字排序

    在Java编程语言中,对包含中文、数字和字母的数据进行排序是一项常见的任务。这个场景下,我们关注的是如何实现一个自定义的排序规则,按照数字、字母和汉字的顺序进行排列。以下是对这一主题的详细解释。 首先,...

    Java 实现ip 地址排序

    Java ip 地址排序Java ip 地址排序Java ip 地址排序Java ip 地址排序

    java冒泡排序代码

    java冒泡排序代码,亲测能用,控制台输入数据,自动排序

    java 中文姓氏 排序

    ### Java 中文姓氏排序详解 #### 一、引言 在处理中文数据时,我们经常需要对含有中文姓名的数据进行排序。Java 提供了多种方式进行排序,包括使用 `Collections.sort()` 方法配合自定义比较器(`Comparator`)。...

    java基础冒泡排序.ppt

    Java基础知识: 冒泡排序详解,简单而详细的讲清楚了,什么是冒泡排序。 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如...

    java数组排序

    在Java编程语言中,数组排序是一项基础且重要的任务。它涉及到不同的算法,这些算法通过比较和交换元素来达到数组元素的有序状态。本篇将详细探讨几种常见的排序算法及其在Java中的实现。 首先,让我们从最简单的...

    JAVA 8种排序介绍及实现

    本文将介绍两种常见的排序算法:直接插入排序和希尔排序,并通过Java代码实现来帮助理解。 1. 直接插入排序(直接插入排序) 直接插入排序是一种简单的排序方法,它的工作原理类似于我们平时手动整理扑克牌。在排序...

    java List 排序 Collections.sort

    总结起来,`Collections.sort()`是Java中对List进行排序的标准工具,它支持自然排序和自定义排序。了解其工作原理和优化技巧,可以帮助我们在编程实践中更高效地处理数据。通过阅读和理解`Collections.sort()`的源码...

    Java 选择排序 算法

    7. **对比其他排序算法** - 相比于快速排序、归并排序或堆排序等高效算法,选择排序在大多数情况下效率较低,但在最坏、最好和平均情况下,时间复杂度都是O(n^2)。 - 与其他简单的排序算法如冒泡排序相比,选择...

    java冒泡排序java冒泡排序集锦方法!

    以上三个知识点总结了关于 Java 排序的一些基本应用,包括基础的冒泡排序算法、使用标准库 `Collections.sort()` 进行排序以及使用 `RuleBasedCollator` 实现国际化排序等。这些技术对于编写高效、可维护的 Java ...

    JAVA排序汇总 各种排序

    7. 计数排序(Counting Sort) 计数排序不是基于比较的排序,它适用于非负整数排序,通过统计每个数字出现的次数,直接确定每个数字在输出序列的位置。时间复杂度为O(n + k),其中k为整数范围。 8. 桶排序(Bucket ...

    java 集合分组与排序

    下面我们将深入探讨如何在Java中实现集合的分组与排序。 1. **集合分组**: 集合分组通常涉及到`GroupingBy`操作,这在Java 8引入的流(Stream)API中得到了很好的支持。`Collectors.groupingBy`方法允许我们将...

    java排序.txt

    根据提供的文件信息,我们可以归纳出以下关于Java排序的相关知识点: ### 一、文件基本信息 - **文件名**:`java排序.txt` - **文件描述**:该文本文件主要介绍了几种常用的Java排序算法,并通过示例代码展示了...

    堆排序7.java 使用java实现的堆排序

    堆排序7.java 使用java实现的堆排序堆排序7.java 使用java实现的堆排序堆排序7.java 使用java实现的堆排序堆排序7.java 使用java实现的堆排序堆排序7.java 使用java实现的堆排序堆排序7.java 使用java实现的堆排序堆...

    Java三种排序 Java三种排序

    在Java编程语言中,有多种排序算法可供使用。这里我们将探讨三种基本的排序算法:冒泡排序、选择排序和插入排序。这些算法都是基于数组的简单排序方法,适合理解排序的基本原理。 首先,我们来看冒泡排序。冒泡排序...

    Java各种排序算法代码.zip

    7. 计数排序(Counting Sort)、桶排序(Bucket Sort)和基数排序(Radix Sort): 这些排序算法适用于特定类型的数据,例如非负整数。计数排序统计每个元素出现的次数,桶排序将元素分布到多个桶中,基数排序则根据...

    java 选择排序法

    在Java中实现选择排序,我们通常会用到数组这一数据结构。 首先,我们要理解Java中的数组。数组是一种线性数据结构,它将相同类型的元素存储在连续的内存位置中,通过索引来访问这些元素。在Java中,声明数组时需要...

    java数组自定义排序

    java中数组的自定义排序,种类繁多,简单实现,可自由操控。

Global site tag (gtag.js) - Google Analytics