首页 > 其他 > 详细

JDK源码阅读之Arrays

时间:2014-03-26 18:16:32      阅读:463      评论:0      收藏:0      [点我收藏+]

Arrays是一个工具类,提供了排序,搜索等的操作方法,Arrays提供的方法都是静态方法,Arrays的构造函数是私有的,也就是不能被实例化,同时,我们可以从名称可以看到Arrays操作的数据都是以数组的形式进行的,Collection里面的排序和搜索都是将Collection转换为Array之后进行,看看神秘的JDK的排序和搜索是怎么实现的?

public class Arrays {//类的构造函数是私有的
    private Arrays() {}
    ........
//整数数组的排序,升序排列,如果需要降序,则自行处理
public static void sort(int[] a) {
     /*
      JDK1.7的排序算法使用了DulaPivotQuickSort算法,该算法是快排的一种变种算法,
      据介绍其没有快排失效导致o(n*n)的情况,关于算法实现,表示没看懂!!
      */
     DualPivotQuicksort.sort(a);
}
//基本类型的排序都使用该排序算法
public static void sort(double[] a) {
        DualPivotQuicksort.sort(a);
}
//对象的排序,对象必须是可比较的,即必须实现Compareable接口
public static void sort(Object[] a) {
        if (LegacyMergeSort.userRequested)//虚拟机参数,需要配置
            legacyMergeSort(a);//用合并排序算法,需要额外的一倍空间
        else
            ComparableTimSort.sort(a);//用二分排序算法
}
//合并排序算法的实现,要排序src,但是需要dest来配合
private static void mergeSort(Object[] src, Object[] dest,int low,int high, int off) {
        int length = high - low;
        //在小数据集上面之间用插入排序算法,即长度小于7时
        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--) //用Comparable的排序接口
                    swap(dest, j, j-1);//交换两个元素
            return;
        }
        //元素长度大于7时,按合并排序算法进行排序
        int destLow  = low;
        int destHigh = high;
        low  += off;
        high += off;
        int mid = (low + high) >>> 1;
        mergeSort(dest, src, low, mid, -off);//从low到mid的元素进行合并排序
        mergeSort(dest, src, mid, high, -off);//从mid到high的元素进行合并排序
        //如果两部分已经有序,则执行复制元素即可
        if (((Comparable)src[mid-1]).compareTo(src[mid]) <= 0) {
            System.arraycopy(src, low, dest, destLow, length);
            return;        }
        //进行合并操作
        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++];
        }
}
//二分搜索算法,这里要求a是有序的,否则结果不确定
public static int binarySearch(long[] a, long key) {
        return binarySearch0(a, 0, a.length, key);
}
//执行二分搜索
private static int binarySearch0(long[] a, int fromIndex, int toIndex,
                                     long key) {
        int low = fromIndex;
        int high = toIndex - 1;
        while (low <= high) {
            int mid = (low + high) >>> 1;//用移位运算实现除法
            long midVal = a[mid];
            if (midVal < key)
                low = mid + 1;
            else if (midVal > key)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.
}
//对象的二分搜索
private static int binarySearch0(Object[] a, int fromIndex, int toIndex,
                                     Object key) {
        int low = fromIndex;
        int high = toIndex - 1;
        while (low <= high) {
            int mid = (low + high) >>> 1;
            Comparable midVal = (Comparable)a[mid];
            int cmp = midVal.compareTo(key);//用Compareable的排序接口
            if (cmp < 0)
                low = mid + 1;
            else if (cmp > 0)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.   
}
//这里看看数组的比较算法是怎么做的,这里程序考虑很全面,值得大家学习
public static boolean equals(byte[] a, byte[] a2) {
        if (a==a2)//指向同一个值
            return true;
        if (a==null || a2==null)
            return false;
        int length = a.length;
        if (a2.length != length)//数组长度的比较
            return false;
        for (int i=0; i<length; i++)
            if (a[i] != a2[i])//值的比较
                return false;
        return true;
}
//填充算法,Java没有类似C的memset,不然效率更高
public static void fill(char[] a, char val) {
        for (int i = 0, len = a.length; i < len; i++)
            a[i] = val;
}
//计算Hash值的算法
public static int hashCode(byte a[]) {
        if (a == null)
            return 0;
        int result = 1;
        for (byte element : a)
            result = 31 * result + element;//使用了Time31的Hash算法
        return result;
}


JDK源码阅读之Arrays,布布扣,bubuko.com

JDK源码阅读之Arrays

原文:http://blog.csdn.net/lcli2009/article/details/22172087

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!