详解Arrays类的底层源码

1.给数据排序【Arrays.sort()】
//对整型数组进行排序
public static void sort(int[] a) {
    //底层使用的是快速排序【时间复杂度:O(nlongN)】
    DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}

//对给定范围的期间内进行排序 ---> [fromIndex,toIndex)
public static void sort(int[] a, int fromIndex, int toIndex) {
    //检查期间是否在符合的长度内
    rangeCheck(a.length, fromIndex, toIndex);
    //快排
    DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0);
}

 

 2.二分查找【Arrays.binarySearch()】 

注:要想进行二分查找,数据必须是有序的,有返回值

//在数组a中查找key的值
public static int binarySearch(int[] a, int key) {
    return binarySearch0(a, 0, a.length, key);
}

//给定的区间内进行查找
public static int binarySearch(int[] a, int fromIndex, int toIndex, int key) {
    //检查给定的区间是否有效
    rangeCheck(a.length, fromIndex, toIndex);
    return binarySearch0(a, fromIndex, toIndex, key);
}

//二分查找的底层源码分析
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                 int key) {
    int low = fromIndex;
    int high = toIndex - 1;
        
    //在low-high区间走查找key值
    while (low <= high) {
        //取low-high的中间值
        int mid = (low + high) >>> 1;
        int midVal = a[mid];
        
        if (midVal < key) //中间值小于目标值,则往右边查找
            low = mid + 1;
        else if (midVal > key) //中间值大于目标值,往左边查找
            high = mid - 1;
        else
            return mid; //找到了,返回下标
    }
    //若不存在目标值,则返回应该存在下标的相反数
    return -(low + 1);  
}

 

 3.判断两个数组是否相等【Arrays.equals()】
//判断两个整型数组是否相同
public static boolean equals(int[] a, int[] 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

 

4.数组填充【Arrays.fill()】
//把数组中的值全部填充为val
public static void fill(int[] a, int val) {
    for (int i = 0, len = a.length; i < len; i++)
        a[i] = val;
}

//把数组中fromIndex到toIndex的下标填充为val
public static void fill(int[] a, int fromIndex, int toIndex, int val) {
    //检查期间的的合法性
    rangeCheck(a.length, fromIndex, toIndex);
    for (int i = fromIndex; i < toIndex; i++)
        a[i] = val;
}

 

5.数组拷贝【Arrays.copyOf()】
//把数组拷贝到另一个数组中去
public static int[] copyOf(int[] original, int newLength) {
    //申请新数组的空间,newLength新数组的长度
    int[] copy = new int[newLength];
    //进行拷贝
    System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
    //返回拷贝后的数组
    return copy;
}

//底层分析
System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
1) original: 给定数组/被复制的数组
2) 0: 被复制的数组从那个下标开始复制
3) copy: 新数组/拷贝数组
4) 0: 从新数组的那个地方开始进行拷贝
5) Math.min(original.length, newLength): 取两者的最小值作为拷贝长度

//System.arraycopy的底层代码
public static native void arraycopy(Object src,  int  srcPos,
                                    Object dest, int destPos,
                                    int length);

//在给定的范围进行拷贝
public static int[] copyOfRange(int[] original, int from, int to) {
    //新数组的长度
    int newLength = to - from;
    //若长度小于0,抛出异常
    if (newLength < 0)
        throw new IllegalArgumentException(from + " > " + to);
    //申请新数组的空间
    int[] copy = new int[newLength];
    //进行拷贝
    System.arraycopy(original, from, copy, 0,
                     Math.min(original.length - from, newLength));
    return copy;
}

 

6.获取数组的哈希值【Arrays.hashCode()】
//整型数组哈希值的获取
public static int hashCode(int a[]) {
    //数组为空,哈希值为0
    if (a == null)
        return 0;

    int result = 1;
    //进行哈希值的计算
    for (int element : a)
        result = 31 * result + element;
    
    //返回哈希值
    return result;
}

//Object数组哈希值的获取
public static int hashCode(Object a[]) {
    if (a == null)
        return 0;

    int result = 1;
    
    //根据类型来进行哈希值的计算
    for (Object element : a)
        result = 31 * result + (element == null ? 0 : element.hashCode());

    return result;
}

 

7.把数组转为字符串【Arrays.toString】
//把整型数组转化为字符串
public static String toString(int[] a) {
    //数组为空,直接返回空
    if (a == null)
        return "null";
    int iMax = a.length - 1;
    //空数组
    if (iMax == -1)
        return "[]";
    
    //使用StringBuilder进行拼接
    StringBuilder b = new StringBuilder();
    b.append('[');
    for (int i = 0; ; i++) {
        b.append(a[i]);
        if (i == iMax)
            return b.append(']').toString(); //返回字符串
        b.append(", ");//拼接逗号
    }
}

//Object数组转化为字符串
public static String toString(Object[] a) {
    if (a == null)
        return "null";

    int iMax = a.length - 1;
    if (iMax == -1)
        return "[]";

    StringBuilder b = new StringBuilder();
    b.append('[');
    for (int i = 0; ; i++) {
        //valueOf方法的底层会把这个类型的数据转化为字符串【调用了toString方法】
        b.append(String.valueOf(a[i]));
        if (i == iMax)
            return b.append(']').toString();
        b.append(", ");
    }
}

//valueOf的底层
public static String valueOf(Object obj) {
    //调用类型的toString()方法
    return (obj == null) ? "null" : obj.toString();
}

注:Arrays.deepToString()方法是对二维数组即以上的数组进行“数组转化为字符串的” 

你可能感兴趣的:(java,开发语言)