详解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<length; i++)
        if (a[i] != a2[i])
            return false;

    return true;
}

//判断两个Object数组是否相同
public static boolean equals(Object[] a, Object[] a2) {
    //判断是否为同一个数组
    if (a==a2)
        return true;
    //判断是否有空数组
    if (a==null || a2==null)
        return false;

    int length = a.length;
    //判断长度是否不同
    if (a2.length != length)
        return false;
    
    //比较Object数组中的值是否相同
    for (int i=0; i<length; i++) {
        Object o1 = a[i];
        Object o2 = a2[i];
        //比较使用equals方法
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    }

    return true;
}

 

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()方法是对二维数组即以上的数组进行“数组转化为字符串的” 

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
arrays.copyOf是Java中的一个方法,用于复制一个数组。 它的码如下: ```java public static <T> T[] copyOf(T[] original, int newLength) { return (T[]) copyOf(original, newLength, original.getClass()); } public static <T, U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; } ``` 首先,copyOf方法是一个重载的方法,它有两个版本。第一个版本传入两个参数,分别是原始数组和新数组的长度。第二个版本传入三个参数,分别是原始数组,新数组的长度以及新数组的类型。 在第一个版本中,方法内部调用了第二个版本的方法,并且将原始数组的类型传递给了新数组的类型。 在第二个版本中,根据新数组的类型创建了一个新的数组对象copy。如果新数组的类型是Object数组,则直接创建一个新的Object数组;如果新数组的类型不是Object数组,则通过Array.newInstance方法创建指定类型的新数组。 然后,使用System.arraycopy方法将原始数组的元素复制到新数组中。该方法会复制原始数组的前Math.min(original.length, newLength)个元素,确保不会超出新数组的长度。 最后,将复制后的数组返回。 总结来说,arrays.copyOf方法就是根据给定的原始数组和长度复制出一个新的数组,并返回该新数组。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值