兩年前,我甚至寫過一篇文章,吐槽數組在 Java 中挺雞肋的,由於有 List 誰用數組啊,如今想一想那時候的本身好幼稚,好好笑。由於我只看到了表面現象,實際上呢,List 的內部仍然是經過數組實現的,好比說 ArrayList,在它的源碼裏能夠看到下面這些內容:java
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
數組在 Java 中,必須算是核心,神通常的存在。git
按照 Javadoc 給出的解釋,數組是一個對象,它包含了一組固定數量的元素,而且這些元素的類型是相同的。數組會按照索引的方式將元素放在指定的位置上,意味着咱們能夠經過索引來訪問到這些元素。在 Java 中,索引是從 0 開始的。程序員
咱們能夠將數組理解爲一個個整齊排列的單元格,每一個單元格里面存放着一個元素。github
數組元素的類型能夠是基本數據類型(好比說 int、double),也能夠是引用數據類型(好比說 String),包括自定義類型的對象。web
瞭解了數組的定義後,讓咱們來深刻地研究一下數組的用法。面試
在 Java 中,數組的聲明方式有兩種。json
先來看第一種:數組
int[] anArray;
再來看第二種:微信
int anOtherArray[];
不一樣之處就在於中括號的位置,是緊跟類型,仍是放在變量名的後面。前者比後者的使用頻率更高一些。app
接下來就該看看怎麼初始化數組了,一樣有多種方式能夠初始化數組,好比說最多見的是:
int[] anArray = new int[10];
使用了 new 關鍵字,對吧?這就意味着數組的確是一個對象。而後,在方括號中指定了數組的長度,這是必須的。
這時候,數組中的每一個元素都會被初始化爲默認值,int 類型的就爲 0,Object 類型的就爲 null。
另外,還可使用大括號的方式,直接初始化數組中的元素:
int anOtherArray[] = new int[] {1, 2, 3, 4, 5};
這時候,數組的元素分別是 一、二、三、四、5,索引依次是 0、一、二、三、4。
前面提到過,能夠經過索引來訪問數組的元素,就像下面這樣:
anArray[0] = 10;
System.out.println(anArray[0]);
經過數組的變量名,加上中括號,加上元素的索引,就能夠訪問到數組,經過「=」操做符進行賦值。
若是索引的值超出了數組的界限,就會拋出 ArrayIndexOutOfBoundException
,關於這方面的知識,我以前特地寫過一篇文章,若是你感興趣的話,能夠跳轉過去看看。
爲何會發生ArrayIndexOutOfBoundsException
我以爲緣由挺有意思的。
既然數組的索引是從 0 開始,那就是到數組的 length - 1
結束,不要使用超出這個範圍內的索引訪問數組,就不會拋出數組越界的異常了。
當數組的元素很是多的時候,逐個訪問數組就太辛苦了,因此須要經過遍歷的方式。
第一種,使用 for 循環:
int anOtherArray[] = new int[] {1, 2, 3, 4, 5};
for (int i = 0; i < anOtherArray.length; i++) {
System.out.println(anOtherArray[i]);
}
經過 length 屬性獲取到數組的長度,而後索引從 0 開始遍歷,就獲得了數組的全部元素。
第二種,使用 for-each 循環:
for (int element : anOtherArray) {
System.out.println(element);
}
若是不須要關心索引的話(意味着不須要修改數組的某個元素),使用 for-each 遍歷更簡潔一些。固然,也可使用 while 和 do-while 循環。
可變參數用於將任意數量的參數傳遞給方法:
void varargsMethod(String... varargs) {}
varargsMethod()
方法能夠傳遞任意數量的字符串參數,能夠是 0 個或者 N 個,本質上,可變參數就是經過數組實現的,爲了證實這一點,咱們能夠經過 jad 反編譯一下字節碼:
public class VarargsDemo
{
public VarargsDemo()
{
}
transient void varargsMethod(String as[])
{
}
}
因此咱們其實能夠直接將數組做爲參數傳遞給可變參數的方法:
VarargsDemo demo = new VarargsDemo();
String[] anArray = new String[] {"沉默王二", "一枚有趣的程序員"};
demo.varargsMethod(anArray);
也能夠直接傳遞多個字符串,經過逗號隔開的方式:
demo.varargsMethod("沉默王二", "一枚有趣的程序員");
List 封裝了不少經常使用的方法,方便咱們對集合進行一些操做,而若是直接操做數組的話,多有不便,所以有時候咱們須要把數組轉成 List。
最原始的方式,就是經過遍歷數組的方式,一個個將數組添加到 List 中。
int[] anArray = new int[] {1, 2, 3, 4, 5};
List<Integer> aList = new ArrayList<>();
for (int element : anArray) {
aList.add(element);
}
更優雅的方式是經過 Arrays 類的 asList()
方法:
List<Integer> aList = Arrays.asList(anArray);
但須要注意的是,該方法返回的 ArrayList 並非 java.util.ArrayList
,它實際上是 Arrays 類的一個內部類:
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable{}
若是須要添加元素或者刪除元素的話,最好把它轉成 java.util.ArrayList
。
new ArrayList<>(Arrays.asList(anArray));
Java 8 新增了 Stream 流的概念,這就意味着咱們也能夠將數組轉成 Stream 進行操做,而不是 List。
String[] anArray = new String[] {"沉默王二", "一枚有趣的程序員", "好好珍重他"};
Stream<String> aStream = Arrays.stream(anArray);
也能夠直接對數組的元素進行剪輯,經過指定索引的方式:
Stream<String> anotherStream = Arrays.stream(anArray, 1, 3);
結果包含"一枚有趣的程序員"和"好好珍重他",1 這個索引位置包括,3 這個索引位置不包括。
Arrays 類提供了一個 sort()
方法,能夠對數組進行排序。
compareTo()
的排序來看第一個例子:
int[] anArray = new int[] {5, 2, 1, 4, 8};
Arrays.sort(anArray);
排序後的結果以下所示:
[1, 2, 4, 5, 8]
來看第二個例子:
String[] yetAnotherArray = new String[] {"A", "E", "Z", "B", "C"};
Arrays.sort(yetAnotherArray, 1, 3,
Comparator.comparing(String::toString).reversed());
只對 1-3 位置上的元素進行反序,因此結果以下所示:
[A, Z, E, B, C]
有時候,咱們須要從數組中查找某個具體的元素,最直接的方式就是經過遍歷的方式:
int[] anArray = new int[] {5, 2, 1, 4, 8};
for (int i = 0; i < anArray.length; i++) {
if (anArray[i] == 4) {
System.out.println("找到了 " + i);
break;
}
}
上例中從數組中查詢元素 4,找到後經過 break 關鍵字退出循環。
若是數組提早進行了排序,就可使用二分查找法,這樣效率就會更高一些。Arrays.binarySearch()
方法可供咱們使用,它須要傳遞一個數組,和要查找的元素。
int[] anArray = new int[] {1, 2, 3, 4, 5};
int index = Arrays.binarySearch(anArray, 4);
除了一維數組,還有二維數組,但說實話,二維數組不太經常使用,這裏就再也不介紹了,感興趣的話,能夠嘗試打印如下楊輝三角。
這篇文章,咱們介紹了 Java 數組的基本用法和一些高級用法,我想小夥伴們應該已經徹底掌握了。
我是沉默王二,一枚有趣的程序員。若是以爲文章對你有點幫助,請微信搜索「 沉默王二 」第一時間閱讀。
本文 GitHub 已經收錄,有大廠面試完整考點,歡迎 Star。
原創不易,莫要白票,請你爲本文點個贊吧,這將是我寫做更多優質文章的最強動力。