jdk原始碼閱讀之Arrays
阿新 • • 發佈:2019-01-11
Arrays實現了陣列常見的一些操作,比如:排序、陣列拷貝等。
Arrays類為了通用性,對方法進行了大量的過載,在這裡只講通用的。
public static void sort(Object[] a) {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a);
else
ComparableTimSort.sort(a, 0, a.length, null, 0, 0);
}
進行排序的陣列一定要實現Comparable介面,否則會報錯,舉個例子:
import java.util.Arrays; class A implements Comparable<A> { private int i; public A(int i) { this.i = i; } @Override public int compareTo(A o) { int oi = o.i; return i > oi ? 1 : (i == oi ? 0 : -1); } public int getI() { return i; } } public class TestDemo1 implements Cloneable { public static void main(String[] args) throws Exception { A[] a = { new A(3), new A(8), new A(4), new A(6), new A(1), }; Arrays.sort(a); for (A a2 : a) { System.out.print(a2.getI()); } } }
這樣陣列a可以正常排序,如果A類沒有實現Comparable介面,在進行排序的時候會報 java.lang.ClassCastException異常。
public static int binarySearch(Object[] a, Object key) { return binarySearch0(a, 0, a.length, key); } private static int binarySearch0(Object[] a, int fromIndex, int toIndex, Object key) { int low = fromIndex; int high = toIndex - 1; while (low <= high) { int mid = (low + high) >>> 1; @SuppressWarnings("rawtypes") Comparable midVal = (Comparable)a[mid]; @SuppressWarnings("unchecked") int cmp = midVal.compareTo(key); if (cmp < 0) low = mid + 1; else if (cmp > 0) high = mid - 1; else return mid; // key found } return -(low + 1); // key not found. }
由程式碼可知,查詢到的依據是兩者的compareTo方法返回的是否是0,而不是呼叫equals方法,這一點要注意。
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;
}
對比兩個陣列的每一個物件呼叫equals方法,如果每個物件呼叫equals都返回0,那麼說明兩個陣列相等。
public static void fill(Object[] a, Object val) {
for (int i = 0, len = a.length; i < len; i++)
a[i] = val;
}
fill方法用來將陣列a的每一個元素都賦值為val,當val是引用的話,那麼陣列的每一個元素都是引用,並且引用的是同一個物件;當val為基本資料型別的話,陣列的每一個元素的值為val。
@SuppressWarnings("unchecked")
public static <T> T[] copyOf(T[] original, int newLength) {
return (T[]) copyOf(original, newLength, original.getClass());
}
@SuppressWarnings("unchecked")
public static <T> T[] copyOfRange(T[] original, int from, int to) {
return copyOfRange(original, from, to, (Class<? extends T[]>) original.getClass());
}
對於copyOf(T[] original, int newLength),當newLength大於origin陣列的長度時,返回的陣列大小為newLength,剩餘的部分用0填充。
對於copyOfRange(T[] original, int from, int to),是部分拷貝。
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
asList方法是一個帶不定引數的方法,把這些引數轉換成List。