1.數(shù)組類型
數(shù)組是編程語(yǔ)言中最常見的一種數(shù)據(jù)結(jié)構(gòu),可用于存儲(chǔ)多個(gè)數(shù)據(jù),每個(gè)數(shù)組元素存放一個(gè)數(shù)據(jù),通常可通過(guò)數(shù)組元素的索引來(lái)訪問(wèn)數(shù)組元素,包括為數(shù)組元素賦值和取出數(shù)組元素的值
理解數(shù)組:數(shù)組也是一種類型
java的數(shù)組要求所有的數(shù)組元素具有相同的數(shù)據(jù)類型,因此在一個(gè)數(shù)組中,數(shù)組元素的類型是唯一的,即一個(gè)數(shù)組里只能存儲(chǔ)一種數(shù)據(jù)類型的數(shù)據(jù),而不能存儲(chǔ)多種數(shù)據(jù)類型的數(shù)據(jù)。
一旦數(shù)組的初始化完成,數(shù)組在內(nèi)存中所占的空間將被固定下來(lái),因此數(shù)組的長(zhǎng)度將不可改變,即使把某個(gè)數(shù)組元素的數(shù)據(jù)清空,但它所占的空間依然被保留。
2.定義數(shù)組
java語(yǔ)言支持兩種語(yǔ)法格式來(lái)定義數(shù)組
type[] arrayName;
type arrayName[];?
對(duì)著兩種語(yǔ)法格式而言,通常推薦使用第一種格式,因?yàn)榈谝环N格式不僅具有更好的語(yǔ)意,而且具有更好的可讀性
數(shù)組是一種引用類型的變量,因此使用它定義一個(gè)變量時(shí),僅僅標(biāo)識(shí)定義了一個(gè)引用變量,這個(gè)引用變量還未指向任何有效的內(nèi)存,因此定義數(shù)組時(shí)不能指定數(shù)組的長(zhǎng)度,而且由于定義數(shù)組只是定義了一個(gè)引用變量,并未指向任何有效的內(nèi)存空間,所以還沒(méi)有內(nèi)存空間來(lái)存儲(chǔ)數(shù)組元素,因此這個(gè)數(shù)組也不能使用,只有對(duì)數(shù)組進(jìn)行初始化后才可以使用。
3.數(shù)組的初始化
java語(yǔ)言中數(shù)組必須先初始化,然后才可以使用,所謂初始化,就是為數(shù)組的數(shù)組元素分配內(nèi)存空間,并為每個(gè)數(shù)組元素賦初始的值。
數(shù)組的初始化有兩種方式:
靜態(tài)初始化:初始化時(shí)由程序員顯式指定每個(gè)數(shù)組元素的初始值,由系統(tǒng)決定數(shù)組長(zhǎng)度。
動(dòng)態(tài)初始化:初始化時(shí)程序員只能指定數(shù)組長(zhǎng)度,有系統(tǒng)為數(shù)組元素分配初始值。
靜態(tài)初始化語(yǔ)法格式如下:
arrayName = new type[] {element1.element2,element3....}
動(dòng)態(tài)初始化語(yǔ)法格式如下:
arrayName = new type[length];
執(zhí)行動(dòng)態(tài)初始化時(shí)程序員只需要指定數(shù)組的長(zhǎng)度,即為每個(gè)數(shù)組元素指定所需的內(nèi)存空間,系統(tǒng)將負(fù)責(zé)為這些數(shù)組元素分配初始值。
數(shù)組元素的類型是基本類型中的整數(shù)類型(byte、short、int、long)則數(shù)組元素的值是0
數(shù)組元素的類型是基本類型中浮點(diǎn)類型(float、double),則數(shù)組元素的值是0.0
數(shù)組元素的類型是基本類型中字符類型(char),則數(shù)組元素的值是'\u0000'
數(shù)組元素的類型是基本類型中布爾類型(boolean),則數(shù)組元素的值是null
4.使用數(shù)組
數(shù)組最常用的用法就是訪問(wèn)數(shù)組元素,包括對(duì)數(shù)組元素進(jìn)行賦值和取出數(shù)組元素的值,訪問(wèn)數(shù)組元素都是通過(guò)在數(shù)組引用變量后緊跟一個(gè)方括號(hào)[],方括號(hào)里是數(shù)組元素的索引值,這樣就可以訪問(wèn)數(shù)組元素了,訪問(wèn)到數(shù)組元素之后,就可以把一個(gè)數(shù)組元素當(dāng)成一個(gè)普通變量使用了,包括為該變量賦值和取出該變量的值,這個(gè)變量的類型就是定義數(shù)組時(shí)使用的類型。
java語(yǔ)言的數(shù)組索引是從0開始的,也就是說(shuō),第一個(gè)數(shù)組元素的索引值為0,最后一個(gè)數(shù)組元素的索引值為數(shù)組長(zhǎng)度減一,
如果訪問(wèn)數(shù)組元素時(shí)指定的索引值小于0,或者大于等于數(shù)組的長(zhǎng)度,編譯程序不會(huì)出現(xiàn)任何錯(cuò)誤,但運(yùn)行時(shí)出現(xiàn)異常:java.lang.ArraryIndexOutOfBoundsException:N(數(shù)組索引越界異常),異常信息后的N就是程序員試圖訪問(wèn)的數(shù)組索引。
所有的數(shù)組都提供了一個(gè)length的屬性,通過(guò)這個(gè)屬性可以訪問(wèn)到數(shù)組的長(zhǎng)度,一旦獲得了數(shù)組的長(zhǎng)度,就可以通過(guò)循環(huán)來(lái)遍歷該數(shù)組的每個(gè)數(shù)組元素。
5.foreach循環(huán)
從java5之后,java提供了一種更簡(jiǎn)單的循環(huán):foreach循環(huán),這種循環(huán)遍歷數(shù)組和集合。使用foreach循環(huán)遍歷數(shù)組和集合元素時(shí),
,無(wú)需獲得數(shù)組和集合的長(zhǎng)度,無(wú)需根據(jù)索引來(lái)訪問(wèn)數(shù)組元素和集合元素,foreach循環(huán)自動(dòng)遍歷數(shù)組和集合的每個(gè)元素。
foreach循環(huán)的語(yǔ)法格式如下:
for(type variableName : array | collection)
{
//variableName 自動(dòng)迭代訪問(wèn)每個(gè)元素
}
foreach循環(huán)和普通循環(huán)不同的是,它無(wú)需循環(huán)條件,無(wú)需循環(huán)迭代語(yǔ)句,這些部分都由系統(tǒng)來(lái)完成,foreach循環(huán)自動(dòng)迭代數(shù)組的每個(gè)元素,每當(dāng)元素都被迭代一次后,foreach循環(huán)自動(dòng)結(jié)束。
6.深入數(shù)組
1)內(nèi)存中的數(shù)組
數(shù)組應(yīng)用變量是訪問(wèn)堆內(nèi)存中數(shù)組元素的根本方式。
定義并初始化一個(gè)數(shù)組后,在內(nèi)存中分配了兩個(gè)空間,一個(gè)用于存放數(shù)組的引用變量,另一個(gè)用于存放數(shù)組本身。
2)基本類型數(shù)組的初始化
對(duì)于基本類型數(shù)組而言,數(shù)組元素的值直接存儲(chǔ)在對(duì)應(yīng)的數(shù)組元素中,因此初始化數(shù)組時(shí),先為該數(shù)組分配內(nèi)存空間,然后直接將數(shù)組元素的值存入對(duì)應(yīng)數(shù)組元素中。
3)引用類型數(shù)組的初始化
每個(gè)數(shù)組元素里存儲(chǔ)的還是引用,它指向另一塊內(nèi)存,這塊內(nèi)存里存儲(chǔ)了有效數(shù)據(jù)。
4)沒(méi)有多維數(shù)組
如果從數(shù)組底層的運(yùn)行機(jī)制上來(lái)看,沒(méi)有多維數(shù)組
java語(yǔ)言里的數(shù)組類型是引用類型,因此數(shù)組變量其實(shí)是一個(gè)引用,這個(gè)引用指向真實(shí)的數(shù)組內(nèi)褲才能。數(shù)組元素的類型也可以是引用,如果數(shù)組元素的引用再次指向真實(shí)的數(shù)組內(nèi)存,這種情形看上去很像多維數(shù)組。
java語(yǔ)言采用上面的語(yǔ)法格式來(lái)定義二維數(shù)組,但它的實(shí)質(zhì)還是一維數(shù)組,只是其數(shù)組元素也是引用,數(shù)組元素里保存的引用指向一維數(shù)組。
7.java8增強(qiáng)的工具類:arrays
java提供的arrays類里包含的一些static修飾的方法可以直接操作數(shù)組,這個(gè)arrays類里包含了如下幾個(gè)static修飾的方法
int binarySearch(type[] a, type key):使用二分法查詢key元素值在a數(shù)組中出現(xiàn)的索引;如果a數(shù)組不包含key元素值,則返回負(fù)數(shù)。調(diào)用該方法時(shí)要求數(shù)組中元素已經(jīng)按升序排列,這樣才能得到正確的結(jié)果。
int binarySearch(type[] a,int fromIndex,int toIndex ,type key):這個(gè)方法和前一個(gè)方法類似,但它只搜索a數(shù)組中fromIndex到toIndex索引的元素。調(diào)用該方法時(shí)要求數(shù)組中元素已經(jīng)按升序排列,這樣才能得到正確的結(jié)果。
type[] copyOf(type[] original,int length):這個(gè)方法將會(huì)把original數(shù)組復(fù)制成一個(gè)新數(shù)組,其中l(wèi)ength是新數(shù)組的長(zhǎng)度。如果length小于original數(shù)組的長(zhǎng)度,則新數(shù)組就是原數(shù)組的前面length個(gè)元素;
type[] copyOfRange(type[] original,int from,int to):這個(gè)方法與前面方法相似,但這個(gè)方法只復(fù)制original數(shù)組的from索引到to索引的元素。
boolean equals(type[] a,type a2):如果a數(shù)組和a2數(shù)組的長(zhǎng)度相等,而且a數(shù)組和a2數(shù)組的數(shù)組元素也一一相同,該方法將返回true。
void fill(type[] a, type val):該方法將會(huì)把a(bǔ)數(shù)組的所有元素都賦值為val。
void fill(type[] a,int fromIndex,int toIndex,type val)
void sort(type[] a)該方法對(duì)a數(shù)組進(jìn)行排序。
void sort(type[] a,int fromIndex,int toIndex)
String toString(type[] a):該方法將一個(gè)數(shù)組轉(zhuǎn)換成一個(gè)字符串。該方法按順序把多個(gè)數(shù)組元素連綴在一起,多個(gè)數(shù)組元素使用英文逗號(hào)和空格隔開。
Arrays類處于java.util包下,為了在程序中使用Arrays類,必須在程序中導(dǎo)入java.util.Arrays類。
void parallelPrefix(xxx[] array,XxxBinaryOperator op):該方法使用op參數(shù)指定的計(jì)算公式計(jì)算得到的結(jié)果作為新的元素。op計(jì)算公式包括left、right兩個(gè)形參,其中l(wèi)eft代表數(shù)組中前一個(gè)索引處的元素,right代表數(shù)組中當(dāng)前索引處的元素,當(dāng)計(jì)算第一個(gè)新數(shù)組元素時(shí),left的值默認(rèn)為1
void setAll(xxx[] array,IntToXxxFunction generator):該方法使用指定的生成器為所有數(shù)組元素設(shè)置值,該生成器控制數(shù)組元素的值得生成算法。
void paralleSetAll(xxx[] array,IntToXxxFunction generator):該方法的功能與上一個(gè)方法相同,只是該方法增加了并行能力,可以利用多CPU并行來(lái)提高性能
void parallelSort(xxx[] a,int fromIndex,int toIndex):該方法與sort()方法相似,該方法增加了并行能力。
Spliterator.OfXxx spliterator(xxx[] array):將數(shù)組的所有元素轉(zhuǎn)換成對(duì)應(yīng)的Spliterator對(duì)象。
XxxStream stream(xxx[] array):該方法將數(shù)組轉(zhuǎn)換為Stream,Stream是java8新增的流式編程的API