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 }
接下来看看:
//复制指定的数组(针对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.
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------
------------------------------------------------------------------------------------