### 概述
Arrays類位于java.util包下,是一個對數組操作的工具類。今天詳細的看了看Arrays類的4千多行源碼,現將Arrays類中的方法做一個總結(JDK版本:1.6.0_34)。Arrays類中的方法可以分為八類:
- sort(對數組排序)
- binarySearch(二分法查找數組中的元素)
- equals(比較兩個數組是否相等)
- fill(對數組中的指定位置填充相同的內容)
- copyOf(數組拷貝)
- asList(將數組轉換為一個固定的List對象)
- hashCode(計算數組的哈希值)
- toString(以特定格式輸出數組)
### 舉例說明
**說明:以下的代碼均為摘抄的java.util.Arrays類中的源碼,注釋為本人所加。**
### sort
~~~
//對數組a進行排序
public static void sort(long[] a) {
sort1(a, 0, a.length);
}
//對數組a中的從fromIndex(包含)至toIndex(不包含)的值進行排序
public static void sort(long[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
sort1(a, fromIndex, toIndex-fromIndex);
}
/**
對基本類型數組的排序有以上兩種方法,這里只摘出了long類型的。sort1方法篇幅原因沒有摘出來,在sort1方法中使用的是經過調優的快速排序算法(tuned quicksort)。
**/
..........
..........
..........
//對對象類型進行排序
public static void sort(Object[] a) {
Object[] aux = (Object[])a.clone();
mergeSort(aux, a, 0, a.length, 0);
}
//對對象a中的從fromIndex(包含)至toIndex(不包含)的值進行排序
public static void sort(Object[] a, int fromIndex, int toIndex) {
rangeCheck(a.length, fromIndex, toIndex);
Object[] aux = copyOfRange(a, fromIndex, toIndex);
mergeSort(aux, a, fromIndex, toIndex, -fromIndex);
}
/**
對對象類型數組的排序有以上兩種方法,在mergeSort方法中使用的是經過修改的歸并排序算法(modified mergesort)。
**/
~~~
### binarySearch
~~~
public static int binarySearch(long[] a, long key) {
return binarySearch0(a, 0, a.length, key);
}
public static int binarySearch(long[] a, int fromIndex, int toIndex,
long key) {
rangeCheck(a.length, fromIndex, toIndex);
return binarySearch0(a, fromIndex, toIndex, key);
}
/**
對數組中元素的查找有以上兩種方法,在binarySearch0方法中使用的是二分查找法。并且對基本類型和對象類型的數組查找是同樣的操作。
**/
~~~
### equals
~~~
//比較基本類型數組是否相等
public static boolean equals(long[] a, long[] 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;
/**
對于double類型,使用的是:
if (Double.doubleToLongBits(a[i])!=Double.doubleToLongBits(a2[i]))
return false;
對于float類型,使用的是:
if (Float.floatToIntBits(a[i])!=Float.floatToIntBits(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;
for (int i=0; i<length; i++) {
Object o1 = a[i];
Object o2 = a2[i];
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
return true;
}
.....
.....
.....
//深度比較兩個數組是否相等
public static boolean deepEquals(Object[] a1, Object[] a2) {
if (a1 == a2)
return true;
if (a1 == null || a2==null)
return false;
int length = a1.length;
if (a2.length != length)
return false;
for (int i = 0; i < length; i++) {
Object e1 = a1[i];
Object e2 = a2[i];
if (e1 == e2)
continue;
if (e1 == null)
return false;
// Figure out whether the two elements are equal
boolean eq;
if (e1 instanceof Object[] && e2 instanceof Object[])
eq = deepEquals ((Object[]) e1, (Object[]) e2);
else if (e1 instanceof byte[] && e2 instanceof byte[])
eq = equals((byte[]) e1, (byte[]) e2);
else if (e1 instanceof short[] && e2 instanceof short[])
eq = equals((short[]) e1, (short[]) e2);
else if (e1 instanceof int[] && e2 instanceof int[])
eq = equals((int[]) e1, (int[]) e2);
else if (e1 instanceof long[] && e2 instanceof long[])
eq = equals((long[]) e1, (long[]) e2);
else if (e1 instanceof char[] && e2 instanceof char[])
eq = equals((char[]) e1, (char[]) e2);
else if (e1 instanceof float[] && e2 instanceof float[])
eq = equals((float[]) e1, (float[]) e2);
else if (e1 instanceof double[] && e2 instanceof double[])
eq = equals((double[]) e1, (double[]) e2);
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
eq = equals((boolean[]) e1, (boolean[]) e2);
else
eq = e1.equals(e2);
if (!eq)
return false;
}
return true;
}
~~~
### fill
~~~
//使用val對a數組進行數據填充
public static void fill(long[] a, long val) {
fill(a, 0, a.length, val);
}
//使用val對a數組從fromIndex(包含)至toIndex(不包含)位置進行數據填充
public static void fill(long[] a, int fromIndex, int toIndex, long val) {
rangeCheck(a.length, fromIndex, toIndex);
for (int i=fromIndex; i<toIndex; i++)
a[i] = val;
}
~~~
### copyOf
~~~
//拷貝從0開始的newLength個
public static byte[] copyOf(byte[] original, int newLength) {
byte[] copy = new byte[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
.....
.....
.....
//拷貝從from(包含)位置到to(不包含)的元素
public static byte[] copyOfRange(byte[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
byte[] copy = new byte[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
/**
拷貝方法有以上兩種,對于基本類型和對象操作是一樣的。而System.arraycopy()方法為淺拷貝,故如果是對象數組的拷貝,只是拷貝了對象的引用,沒有重新new每一個對象。
**/
~~~
### asList
沒有深究。。。。。。
### hashCode
~~~
//對基本數據類型的hashcode的計算
public static int hashCode(long a[]) {
if (a == null)
return 0;
int result = 1;
for (long element : a) {
//對于不同的基本數據類型,計算hashcode的具體操作是不一樣的
int elementHash = (int)(element ^ (element >>> 32));
result = 31 * result + elementHash;
}
return result;
}
....
....
....
//對于Object類型數組的hashcode的計算
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;
}
....
....
....
//對于數組的hashcode值的深度計算
public static int deepHashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a) {
int elementHash = 0;
if (element instanceof Object[])
elementHash = deepHashCode((Object[]) element);
else if (element instanceof byte[])
elementHash = hashCode((byte[]) element);
else if (element instanceof short[])
elementHash = hashCode((short[]) element);
else if (element instanceof int[])
elementHash = hashCode((int[]) element);
else if (element instanceof long[])
elementHash = hashCode((long[]) element);
else if (element instanceof char[])
elementHash = hashCode((char[]) element);
else if (element instanceof float[])
elementHash = hashCode((float[]) element);
else if (element instanceof double[])
elementHash = hashCode((double[]) element);
else if (element instanceof boolean[])
elementHash = hashCode((boolean[]) element);
else if (element != null)
elementHash = element.hashCode();
result = 31 * result + elementHash;
}
return result;
}
~~~
### toString
~~~
//基本數據類型轉字符串
public static String toString(long[] 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++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
.....
.....
.....
//Object類型使用valueOf方法轉字符串
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++) {
b.append(String.valueOf(a[i]));
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
.....
.....
.....
//深度轉換字符串
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;
}
dejaVu.add(a);
buf.append('[');
for (int i = 0; i < a.length; i++) {
if (i != 0)
buf.append(", ");
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());
}
}
}
buf.append(']');
dejaVu.remove(a);
}
~~~