Java中的Arrays,這一篇就夠了
哈嘍,大家好,我是了不起。
JDK中提供了一個(gè)專門用于操作數(shù)組的工具類,即Arrays類,位于java.util 包中。
常用方法
返回類型 | 方法 | 說明 |
String | toString(array) | 將數(shù)組array轉(zhuǎn)換成字符串 |
void | sort(array) | 對(duì)數(shù)組進(jìn)行升序排列。注意:排序算法是由Vladimir Yaroslavskiy,Jon Bentley和Joshua Bloch提供的雙軸快速排序。 |
void | fill(arr,val) | 將數(shù)組arr全部元素賦值為val |
boolean | equals(arr1,arr2) | 判斷兩個(gè)數(shù)組是否相等 |
與arr類型相同 | copyOf(arr,length) | 將數(shù)組arr復(fù)制成一個(gè)長(zhǎng)度為length的新數(shù)組 |
int | binarySearch(arr, val) | 查詢?cè)豽al在arr中的下標(biāo)值 |
示例代碼
public class Test {
public static void main(String[] args) {
int a[]={12,20,13,42,72,26,35,10,46,26,53};
int b[]={3,5,7,8,54,23,9};
int c[]={3,5,7,8,54,23,9};
String str=Arrays.toString(a); //將特定數(shù)組轉(zhuǎn)換成字符串
System.out.println("字符串:"+str);
Arrays.sort(a); //對(duì)數(shù)組array的元素進(jìn)行升序排列
System.out.println("排序后:"+Arrays.toString(a));
Arrays.fill(a,10); //所以元素都賦值成特定值
System.out.println("賦值后:"+Arrays.toString(a));
boolean boo=Arrays.equals(a,b); //判斷兩個(gè)數(shù)組是否相等(對(duì)應(yīng)位置上的元素是否相等)
boolean boo2=Arrays.equals(b, c);
System.out.println("a:"+a);
System.out.println("b:"+b);
System.out.println("c:"+c);
System.out.println("ab相等?"+boo);
System.out.println("bc相等?"+boo2);
int d[]=Arrays.copyOf(b,b.length); //把數(shù)組復(fù)制成特定長(zhǎng)度的數(shù)組,與直接賦值(引用傳遞)不同
System.out.println("d:"+Arrays.toString(d));
System.out.println("d:"+d);
System.out.println("b:"+b);
int i=Arrays.binarySearch(b, 5); //查詢特定因素在數(shù)組中的下標(biāo)
System.out.println("下標(biāo)是:"+i);
}
}
運(yùn)行結(jié)果:
字符串:[12,20,13,42,72,26,35,10,46,26,53]排序后:[10,12,13,20,26,26,35,42,46,53,72]賦值后:「10,10,10,10,10,10,10,10,10,10,10]
a:[I@1606bf5b:[I@14fcc96
c:[I@bcbc
ab相等?false
bc相等?true
d:[3,5,7,8,54,23,9]d:[I@671416b:[I@14fcc96
下標(biāo)是:1
源碼解析
將數(shù)組array轉(zhuǎn)換成字符串
public static String toString(int[] a)
int[] arr = { 24, 69, 80, 57, 13 };
System.out.println("排序前:" + Arrays.toString(arr));
public static String toString(int[] a) {
//a -- arr -- { 24, 69, 80, 57, 13 }
if (a == null)
return "null"; //說明數(shù)組對(duì)象不存在
int iMax = a.length - 1; //iMax=4;
if (iMax == -1)
return "[]"; //說明數(shù)組存在,但是沒有元素。
StringBuilder b = new StringBuilder();
b.append('['); //"["
for (int i = 0; ; i++) {
b.append(a[i]); //"[24, 69, 80, 57, 13"
if (i == iMax)
//"[24, 69, 80, 57, 13]"
return b.append(']').toString();
b.append(", "); //"[24, 69, 80, 57, "
}
}
二分查找
public static int binarySearch(int[] a,int key)
int[] arr = {13, 24, 57, 69, 80};
System.out.println("binarySearch:" + Arrays.binarySearch(arr, 577));
public static int binarySearch(int[] a, int key) {
//a -- arr -- {13, 24, 57, 69, 80}
//key -- 577
return binarySearch0(a, 0, a.length, key);
}
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
int key) {
//a -- arr -- {13, 24, 57, 69, 80}
//fromIndex -- 0
//toIndex -- 5
//key -- 577
int low = fromIndex; //low=0
int high = toIndex - 1; //high=4
while (low <= high) {
int mid = (low + high) >>> 1; //mid=2,mid=3,mid=4
int midVal = a[mid]; //midVal=57,midVal=69,midVal=80
if (midVal < key)
low = mid + 1; //low=3,low=4,low=5
else if (midVal > key)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found.
}
復(fù)制
public static int[] copyOf(int[] original, int newLength)
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
可以看到,最終調(diào)用的是System.arraycopy()方法,由虛擬機(jī)實(shí)現(xiàn),效率自然比用java一個(gè)個(gè)復(fù)制高。
深復(fù)制與淺復(fù)制
- 當(dāng)數(shù)組為一維數(shù)組,且元素為基本類型或String類型時(shí),屬于深復(fù)制,即原數(shù)組與新數(shù)組的元素不會(huì)相互影響。
- 當(dāng)數(shù)組為多維數(shù)組,或一維數(shù)組中的元素為引用類型時(shí),屬于淺復(fù)制,原數(shù)組與新數(shù)組的元素引用指向同一個(gè)對(duì)象。這里說的影響,是兩個(gè)數(shù)組復(fù)制后對(duì)應(yīng)的元素。String的特殊是因?yàn)樗牟豢勺冃浴?/li>
一維數(shù)組,元素為基本類型
public class SystemArrayCopy {
public static void main(String[] args) {
String str1 = "aa";
String str2 = "bb";
String str3 = "cc";
String str4 = "dd";
String[] src = {str1, str2, str3, str4};
String[] dest = new String[4];
System.arraycopy(src, 0, dest, 0, 4);
System.out.println("改變前");
print("src = ", src);
print("dest = ", dest);
src[0] = "abcd";
System.out.println("改變后");
print("src = ", src);
print("dest = ", dest);
}
private static void print(String string, String[] arr) {
System.out.print(string);
for (String str : arr) {
System.out.print(str + " ");
}
System.out.println();
}
}
/*
改變前
src = aa bb cc dd
dest = aa bb cc dd
改變后
src = abcd bb cc dd
dest = aa bb cc dd
*/
可以看到,源數(shù)組第0個(gè)元素改變,并不會(huì)影響到目標(biāo)數(shù)組。
多維數(shù)組
public class SystemArrayCopy {
public static void main(String[] args) {
int[] arr1 = {1, 2};
int[] arr2 = {3, 4};
int[] arr3 = {5, 6};
int[] arr4 = {7, 8};
int[][] src = new int[][]{arr1, arr2, arr3, arr4};
int[][] dest = new int[4][];
System.arraycopy(src, 0, dest, 0, 4);
System.out.println("改變前");
print("src = ", src);
print("dest = ", dest);
src[0][0] = 11111;
System.out.println("改變后");
print("src = ", src);
print("dest = ", dest);
}
// 簡(jiǎn)單輸出二維int數(shù)組的方法
private static void print(String string, int[][] arr) {
System.out.print(string);
for (int[] a : arr) {
for (int i : a) {
System.out.print(i + " ");
}
System.out.print(",");
}
System.out.println();
}
}
/*
改變前
src = 1 2 ,3 4 ,5 6 ,7 8 ,
dest = 1 2 ,3 4 ,5 6 ,7 8 ,
改變后
src = 11111 2 ,3 4 ,5 6 ,7 8 ,
dest = 11111 2 ,3 4 ,5 6 ,7 8 ,
*/
源數(shù)組改變后,目標(biāo)數(shù)組也跟改變了,這就是淺復(fù)制
數(shù)組拷貝的4種方法
1. for循環(huán)
使用for循環(huán)自己實(shí)現(xiàn)數(shù)組的復(fù)制
2. clone
克隆方法我們?cè)跀?shù)組中是找不到的,它是object的方法,我們先看看源碼
protected native Object clone() throws CloneNotSupportedException;
看到了修飾符native,說明是由c或者c++實(shí)現(xiàn)的,它的優(yōu)點(diǎn)是速度快,它返回了object對(duì)象,所以使用的時(shí)候需要用對(duì)象接收返回值。
3. System.arraycopy()
通過上述源碼我們看到也是native修飾的,所以底層也是用c或者c++實(shí)現(xiàn)的,但是可以看到?jīng)]有返回值,clone()還需要對(duì)返回值進(jìn)行類型轉(zhuǎn)換,所以它的速度是要比clone()要快的,這也是??途W(wǎng)的一道題,問的就是四種拷貝哪種是最快的,答案肯定是System.arraycopy()。
4. Arrays.copyof()
在方法內(nèi)部調(diào)用了System.arraycopy(),相當(dāng)于換了名字。
結(jié)語(yǔ)
本次我們介紹了Java中的Arrays的常用方法,Arrays如何去操作數(shù)組、拷貝數(shù)組和打印數(shù)組的方法。






