Arrays类常用方法详解(源码分析)

https://blog.youkuaiyun.com/weixin_69398310/article/details/136574343

一.Arrays.equals()

        众所周知,equals方法是比较里面的内容是否相等的方法,那Arrays中的equals()方法,就是重写了Object中equals(),用来比较数组中的内容是否相等的方法。

下面让我们一起来看一下它的源码:

public static boolean equals(int[] var0, int[] var1) {
    if (var0 == var1) {//判断两个数组的地址是否相同;
        return true;//地址相同的话肯定返回true;
    } else if (var0 != null && var1 != null) {//如果不同,判断是否为空,不为空才进入下面的判断
        int var2 = var0.length;//拿到var0的长度
        if (var1.length != var2) {//判断俩数组长度是否相等
            return false;//长度不同返回false
        } else {
            for(int var3 = 0; var3 < var2; ++var3) {//循环逐个判断其中每个字符是否相等
                if (var0[var3] != var1[var3]) {
                    return false;//但凡有一个不相同,直接返回false
                }
            }
            return true;//其中每个字符都相等,返回true
        }
    } else {
        return false;//如果不符合以上条件,返回false
    }
}

二.Arrays.toString()

        与equals方法一样,Arrays类中的toString()与我们所知道的toString方法的用法是相通的,将数组转换为String格式.

老规矩,让我们继续看一下Arrays类中toString方法的底层实现:

StringBuilder是Java中的另一个类,后期我会对其专门分析:String,StringBuilder,Stringbuffer

public static String toString(int[] var0) {//传进来一个参数var0
        if (var0 == null) {//首先判断他是否为空值--null
            return "null";
        } else {//不为空的话,继续向下判断
            int var1 = var0.length - 1;//拿到数组最大下标
            if (var1 == -1) {//判断该值知否有效
                return "[]";//(即判断是不是空数组)
            } else {
                StringBuilder var2 = new StringBuilder();//创建一个StringBuilder类
                var2.append('[');//给结果集添加[
                int var3 = 0;
 
                while(true) {//遍历整个数组
                    var2.append(var0[var3]);//添加数组中的该值到结果集中
                    if (var3 == var1) {//如果var3==数组最大下标(即:遍历到了最后一项)
                        return var2.append(']').toString();//为结果集加上]
                    }
 
                    var2.append(", ");//添加格式","
                    ++var3;//var3的值+1
                }
            }
        }
    }

三.Arrays.binarySearch(a[], from, to, key);

        binarySearch--二分搜索,Arrays类中定义的可用来以二分搜索的方法是用于在有序数组中查找特定元素的索引。并返回该值的下标,没有的话返回,它会返回一个负数,这个负数是目标元素应该插入的位置的相反数减1。

源码分析:

   >>>是Java中无符号右移操作符,意思是n/2

    public static int binarySearch(int[] var0, int var1, int var2, int var3) {
        rangeCheck(var0.length, var1, var2);//该方法是用来检查传入的from与to是否符合条件
        return binarySearch0(var0, var1, var2, var3);
    }
 
    /**
     *
     * @param var0 传入的数组
     * @param var1 from
     * @param var2 to
     * @param var3 要查找的值
     * @return
     */
    private static int binarySearch0(int[] var0, int var1, int var2, int var3) {
        int var4 = var1;//拿到from的值
        int var5 = var2 - 1;//拿到to的下标
 
        while(var4 <= var5) {//循环
            int var6 = var4 + var5 >>> 1;//得到from与to的一半
            int var7 = var0[var6];//拿到中间元素的值
            if (var7 < var3) {//将该值与目标值进行比对
                var4 = var6 + 1;//该值小于目标值,from变为中间值+1
            } else {
                if (var7 <= var3) {
                    return var6;//在var7<var3的前提下<= 即 var7==var3,
                                //返回中间值(即查找成功)
                }
 
                var5 = var6 - 1;//中间值
            }
        }
 
        return -(var4 + 1);//如果实在查不到,返回from+1的负值
    }

四.Arrays.fill()

        将指定的值分配给指定数组值的指定范围的每个元素。 要填补的范围从索引fromIndex (包括)扩展到索引toIndex ,排他。 (如果是fromIndex==toIndex ,要填充的范围是空的。) 

源码分析: 

    public static void fill(int[] a, int fromIndex, int toIndex, int val) {
        rangeCheck(a.length, fromIndex, toIndex);
        for (int i = fromIndex; i < toIndex; i++)//循环[from,to]
            a[i] = val;//将每个值赋值为val
    }

五.Arrays.hashcode()

        根据指定数组的内容返回哈希码。

源码分析: 

    public static int hashCode(int a[]) {
        if (a == null)
            return 0;
 
        int result = 1;
        for (int element : a)//循环拿出每个值
            result = 31 * result + element;
          //通过将每个元素的值与前一个元素的哈希值进行特定的运算来生成最终的哈希码
        return result;
    }

六.Arrays.copyOfRange()

        指定数组的指定范围复制到新数组中,

    public static int[] copyOfRange(int[] original, int from, int to) {
        int newLength = to - from;//计算范围
        if (newLength < 0)//异常处理,如果范围<0,返回异常
            throw new IllegalArgumentException(from + " > " + to);
        int[] copy = new int[newLength];//new一个数组,长度为需要复制的长度
        System.arraycopy(original, from, copy, 0,
                         Math.min(original.length - from, newLength));
                   //使用arraycopy()方法,将刚才new出来的数组copy到目标数组中
        return copy;
    }

 七.Arrays.deepToString()

        将多维数组转换成字符串形式

   public static String deepToString(Object[] a) {
        if (a == null)
            return "null";

        int bufLen = 20 * a.length;
        if (a.length != 0 && bufLen <= 0)
            bufLen = Integer.MAX_VALUE;
        StringBuilder buf = new StringBuilder(bufLen);    //存放已处理的元素的容器
        deepToString(a, buf, new HashSet<>());
        return buf.toString();
    }

    private static void deepToString(Object[] a, StringBuilder buf,
                                     Set<Object[]> dejaVu) {
        if (a == null) {
            buf.append("null");
            return;
        }
        int iMax = a.length - 1;
        if (iMax == -1) {
            buf.append("[]");
            return;
        }

        dejaVu.add(a);    //如果正处理的元素本身是数组,并且是自身数组的元素,即存在自引用,为了避免无限递归,将正在处理的元素加入已处理的集合中
        buf.append('[');
        for (int i = 0; ; i++) {

            Object element = a[i];
            if (element == null) {
                buf.append("null");
            } else {
                Class<?> eClass = element.getClass();    

                if (eClass.isArray()) {        //元素为一维数组,调用一维数组的转换
                    if (eClass == byte[].class)
                        buf.append(toString((byte[]) element));
                    else if (eClass == short[].class)
                        buf.append(toString((short[]) element));
                    else if (eClass == int[].class)
                        buf.append(toString((int[]) element));
                    else if (eClass == long[].class)
                        buf.append(toString((long[]) element));
                    else if (eClass == char[].class)
                        buf.append(toString((char[]) element));
                    else if (eClass == float[].class)
                        buf.append(toString((float[]) element));
                    else if (eClass == double[].class)
                        buf.append(toString((double[]) element));
                    else if (eClass == boolean[].class)
                        buf.append(toString((boolean[]) element));
                    else { // element is an array of object references
                        if (dejaVu.contains(element))    //如果指定的数组包含自身作为元素,或者包含通过一级或多级数组间接引用自身,则自引用将转换为字符串“[...]”
                            buf.append("[...]");
                        else
                            deepToString((Object[])element, buf, dejaVu);    //元素依然为多维数组,递归处理
                    }
                } else {  // element is non-null and not an array
                    buf.append(element.toString());
                }
            }
            if (i == iMax)
                break;
            buf.append(", ");
        }
        buf.append(']');
        dejaVu.remove(a);
    }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值