• JDK源码(1.7) -- java.util.Arrays


    java.util.Arrays 源码分析

    ---------------------------------------------------------------------------------

    java.util.Arrays是一个工具类,它的定义如下:

     1 public class Arrays {
     2     //Sorting of primitive type arrays.
     3 
     4     // Searching
     5 
     6     // Equality Testing
     7 
     8     // Filling
     9 
    10     // Cloning
    11 
    12     //hashCode
    13 
    14     //toString
    15 }

    从上面的定义可以看出java.util.Arrays这个类包含用来操作数组的各种方法

    ------------------------------------------------------------------------------------

    下面来看看java.util.Arrays中具体有哪些方法

    copyOf(T[] original,int newLength) 复制指定的数组
    copyOfRange(T[] original,int from,int to) 将指定数组的指定范围复制到一个新数组
    binarySearch(Object[] a,Object key) 使用二分搜索法来搜索指定数组,以获得指定对象
    deepEquals(Object[] a1,Object[] a2) 如果两个指定数组彼此是深层相等的,则返回true
    deepHashCode(Object[] a) 基于指定数组的"深层内容"返回哈希值
    deepToString(Object[] a) 返回指定数组"深层内容"的字符串表示形式
    equals(Object[] a,Object[] a2) 如果两个指定的Object数组相等,则返回true
    fill(Object[] a,Object val) 将指定的Object引用分配给指定Object数组的每个元素
    hashCode(Object[] a) 基于指定数组的内容返回哈希码
    sort(Object[] a) 根据元素的自然顺序对指定对象数组按升序进行排序
    toString(Object[] a) 返回指定数组内容的字符串表示形式
    asList(T ... a) 返回一个受指定数组支持的固定大小的列表

    ------------------------------------------------------------------------------------

    java.util.Arrays中的copy方法:

     1 //复制指定的数组(针对boolean类型)
     2 public static boolean[] copyOf(boolean[] original,int newLength)
     3 
     4 //复制指定的数组(针对byte类型)
     5 public static byte[] copyOf(byte[] original,int newLength)
     6 
     7 //复制指定的数组(针对char类型)
     8 public static char[] copyOf(char[] original, int newLength)
     9 
    10 //复制指定的数组(针对double类型)
    11 public static double[] copyOf(double[] original, int newLength)
    12 
    13 //复制指定的数组(针对float类型)
    14 public static float[] copyOf(float[] original, int newLength)
    15 
    16 //复制指定的数组(针对int类型)
    17 public static int[] copyOf(int[] original, int newLength)
    18 
    19 //复制指定的数组(针对long类型)
    20 public static long[] copyOf(long[] original,int newLength)
    21 
    22 //复制指定的数组(针对short类型)
    23 public static short[] copyOf(short[] original,int newLength)
    24 
    25 //复制指定的数组(针对T类型)
    26 public static <T> T[] copyOf(T[] original, int newLength)
    27 
    28 //复制指定的数组(针对T类型)
    29 public static <T,U> T[] copyOf(U[] original, int newLength,Class<? extends T[]> newType)

    在对copy方法进行详细介绍之前,必须先来看看java.lang.System类中的arraycopy方法,因为java.util.Arrays类中的copy方法都是基于java.lang.System类的arraycopy方法实现的。

    /*
    从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。从 src 引用的源数组到 dest 引用的目标数组,数组组件的一个子序列被复制下来。被复制的组件的编号等于 length 参数。源数组中位置在 srcPos 到 srcPos+length-1 之间的组件被分别复制到目标数组中的 destPos 到 destPos+length-1 位置。
    如果参数 src 和 dest 引用相同的数组对象,则复制的执行过程就好像首先将 srcPos 到 srcPos+length-1 位置的组件复制到一个带有 length 组件的临时数组,然后再将此临时数组的内容复制到目标数组的 destPos 到 destPos+length-1 位置一样。
    
    如果 dest 为 null,则抛出 NullPointerException 异常。
    如果 src 为 null, 则抛出 NullPointerException 异常,并且不会修改目标数组。
    否则,只要下列任何情况为真,则抛出 ArrayStoreException 异常并且不会修改目标数组:
      src 参数指的是非数组对象。   dest 参数指的是非数组对象。   src 参数和 dest 参数指的是那些其组件类型为不同基本类型的数组。   src 参数指的是具有基本组件类型的数组且 dest 参数指的是具有引用组件类型的数组。   src 参数指的是具有引用组件类型的数组且 dest 参数指的是具有基本组件类型的数组。 否则,只要下列任何情况为真,则抛出 IndexOutOfBoundsException 异常,并且不会修改目标数组:   srcPos 参数为负。   destPos 参数为负。   length 参数为负。   srcPos+length 大于 src.length,即源数组的长度。   destPos+length 大于 dest.length,即目标数组的长度。 否则,如果源数组中 srcPos 到 srcPos+length-1 位置上的实际组件通过分配转换并不能转换成目标数组的组件类型,则抛出 ArrayStoreException 异常。在这种情况下,将 k 设置为比长度小的最小非负整数,这样就无法将 src[srcPos+k] 转换为目标数组的组件类型;当抛出异常时,从 srcPos 到 srcPos+k-1 位置上的源数组组件已经被复制到目标数组中的 destPos 到 destPos+k-1 位置,而目标数组中的其他位置不会被修改。
    */ public static native void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);

    下面以基本类型int来举例说明:

    源代码如下:

    1     public static int[] copyOf(int[] original, int newLength) {
    2         //创建一个长度为newLength的int类型数组
    3         int[] copy = new int[newLength];
    4 
    5         //复制指定的数组
    6         System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
    8         return copy;
    9     }

    示例代码:

     1 public class ArraysTest {
     2 
     3     public static void main(String[] args) {
     4         //源数组
     5         int[] original = {7,5,1,9,14,11,19,33,21};
     6         
     7         //通过java.util.Arrays类的copyOf方法对源数组进行复制
     8         int[] dest = Arrays.copyOf(original, 4);
     9         for(int i = 0;i < dest.length;i++){
    10             System.out.print(dest[i] + " ");
    11         }
    12         System.out.println();
    13         System.out.println("---------------------");
    14         //通过java.util.Arrays类的copyOf方法对源数组进行复制(如果复制的长度超过了源数组的长度,则用0填充)
    15         int[] dest1 = Arrays.copyOf(original, 20);
    16         for(int i = 0;i < dest1.length;i++){
    17             System.out.print(dest1[i] + " ");
    18         }
    19     }
    20 }
    21 
    22 运行结果:
    23 7 5 1 9 
    24 ---------------------
    25 7 5 1 9 14 11 19 33 21 0 0 0 0 0 0 0 0 0 0 0 

    接下来看看基本类型: byte、short、long、char、float、double、boolean的copyOf方法

    源代码如下:

     1     public static byte[] copyOf(byte[] original, int newLength) {
     2         //创建一个长度为newLength的的byte数组
     3         byte[] copy = new byte[newLength];
     4         //复制数组
     5         System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
     6         return copy;
     7     }
     8 
     9     public static short[] copyOf(short[] original, int newLength) {
    10         //创建一个长度为newLength的的short数组
    11         short[] copy = new short[newLength];
    12         //复制数组
    13         System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
    14         return copy;
    15     }
    16 
    17 
    18     public static long[] copyOf(long[] original, int newLength) {
    19         //创建一个长度为newLength的的long数组
    20         long[] copy = new long[newLength];
    21         //复制数组
    22         System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
    23         return copy;
    24     }
    25 
    26 
    27     public static char[] copyOf(char[] original, int newLength) {
    28         //创建一个长度为newLength的的char数组
    29         char[] copy = new char[newLength];
    30         //复制数组
    31         System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
    32         return copy;
    33     }
    34 
    35 
    36     public static float[] copyOf(float[] original, int newLength) {
    37         //创建一个长度为newLength的的float数组
    38         float[] copy = new float[newLength];
    39         //复制数组
    40         System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
    41         return copy;
    42     }
    43 
    44 
    45     public static double[] copyOf(double[] original, int newLength) {
    46         //创建一个长度为newLength的的double数组
    47         double[] copy = new double[newLength];
    48         //复制数组
    49         System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
    50         return copy;
    51     }
    52 
    53 
    54     public static boolean[] copyOf(boolean[] original, int newLength) {
    55         //创建一个长度为newLength的的boolean数组
    56         boolean[] copy = new boolean[newLength];
    57         //复制数组
    58         System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
    59         return copy;
    60     }
    View Code

    接下来看看:

    //复制指定的数组(针对T类型)
    public static <T> T[] copyOf(T[] original, int newLength)
    
    //复制指定的数组(针对T类型)
    public static <T,U> T[] copyOf(U[] original, int newLength,Class<? extends T[]> newType)

    源代码如下:

     1     public static <T> T[] copyOf(T[] original, int newLength) {
     2         return (T[]) copyOf(original, newLength, original.getClass());
     3     }
     4 
     5 
     6     public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
     7         //创建一个长度为newLength的T类型的数组
     8         T[] copy = ((Object)newType == (Object)Object[].class)
     9             ? (T[]) new Object[newLength]
    10             : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    11 
    12         //复制数组
    13         System.arraycopy(original, 0, copy, 0,Math.min(original.length, newLength));
    14         return copy;
    15     }

    示例代码: 

     1 public class Student {
     2     private String name;
     3     private int age;
     4     
     5     public String getName() {
     6         return name;
     7     }
     8     public void setName(String name) {
     9         this.name = name;
    10     }
    11     public int getAge() {
    12         return age;
    13     }
    14     public void setAge(int age) {
    15         this.age = age;
    16     }
    17     @Override
    18     public String toString() {
    19         return "Student [name=" + name + ", age=" + age + "]";
    20     }
    21     
    22     /**
    23      * 初始化数据,测试时用
    24      * @return
    25      */
    26     public static Student[] initData(){
    27         Student[] stus = new Student[10];
    28         for(int i = 0;i < 10;i++){
    29             Student stu = new Student();
    30             stu.setName("同学"+i);
    31             stu.setAge(i);
    32             stus[i] = stu;
    33         }
    34         return stus;
    35     }
    36 }
    37 
    38 
    39 import java.util.Arrays;
    40 
    41 public class ArraysTest {
    42     public static void main(String[] args) {
    43         //源数组
    44         Student[] stus = Student.initData();
    45         System.out.print("源数组Student[]内容为: ");
    46         for(int i = 0;i < stus.length;i++){
    47             System.out.print(stus[i] + " ");
    48         }
    49         System.out.println();
    50         //通过java.util.Arrays类的copyOf方法对源数组进行复制
    51         Student[] dest = Arrays.copyOf(stus, 6);
    52         System.out.print("复制长度为6的子数组: ");
    53         for(int i = 0;i < dest.length;i++){
    54             System.out.print(dest[i] + " ");
    55         }
    56         System.out.println();
    57         //通过java.util.Arrays类的copyOf方法对源数组进行复制(如果复制的长度超过了源数组的长度,则用0填充)
    58         Student[] dest1 = Arrays.copyOf(stus, 20);
    59         System.out.print("复制长度为20的子数组: ");
    60         for(int i = 0;i < dest1.length;i++){
    61             System.out.print(dest1[i] + " ");
    62         }
    63         System.out.println();
    64     }
    65 }
    66 
    67 运行结果:
    68 源数组Student[]内容为: Student [name=同学0, age=0] Student [name=同学1, age=1] Student [name=同学2, age=2] Student [name=同学3, age=3] Student [name=同学4, age=4] Student [name=同学5, age=5] Student [name=同学6, age=6] Student [name=同学7, age=7] Student [name=同学8, age=8] Student [name=同学9, age=9] 
    69 复制长度为6的子数组: Student [name=同学0, age=0] Student [name=同学1, age=1] Student [name=同学2, age=2] Student [name=同学3, age=3] Student [name=同学4, age=4] Student [name=同学5, age=5] 
    70 复制长度为20的子数组: Student [name=同学0, age=0] Student [name=同学1, age=1] Student [name=同学2, age=2] Student [name=同学3, age=3] Student [name=同学4, age=4] Student [name=同学5, age=5] Student [name=同学6, age=6] Student [name=同学7, age=7] Student [name=同学8, age=8] Student [name=同学9, age=9] null null null null null null null null null null 

     从前面的源代码和示例代码可以看出,java.util.Arrays中的10个copyOf(src,length)方法的作用就是对源数组进行复制,复制的长度为length.

    ------------------------------------------------------------------------------------

    ------------------------------------------------------------------------------------

    ------------------------------------------------------------------------------------

    ------------------------------------------------------------------------------------

  • 相关阅读:
    所遇bug
    PHP后端读取文件给video标签返回视频地址
    element-ui 上传组件 自定义上传没有进度条解决方法
    PHP递归生成分类树
    Vue.js学习 — 微信公众号菜单编辑器(二)
    Vue.js学习 — 微信公众号菜单编辑器(一)
    swiper3插件无缝滚动配置
    PHP获取一周的日期
    bootstrap-select多选下拉列表插件使用小记
    html5小总结
  • 原文地址:https://www.cnblogs.com/xinhuaxuan/p/6372103.html
Copyright © 2020-2023  润新知