下面我帶你們一塊兒加深一下對Java數組的認識:java
1.理解數組express
數組也是一種數據類型,自己就是一種引用類型,咱們從它的初始化方法,經過關鍵字new去完成定義及初始化就能夠知道。數組
數組的長度是不變的,一旦數組完成初始化後,它的長度就固定下來了,在內存中佔有的空間也就固定了,即便裏面的數據被清空了,佔有的空間仍是保留下來了,依然是屬於數組的,固然長度依舊是不變的。ide
數組裏邊存放的數據類型要一致,能夠基本數據類型,也能夠是引用數據類型,可是惟一的標準就是相同的類型。在Java中,類與類是支持繼承關係的,因此就可能形成數組裏面能夠存在多中數據類型的假象:工具
示例:this
class Animal { public String name; public Animal(String name) { this.name = name; } } class Cat extends Animal { public Cat(String name) { super(name); } } class Dog extends Animal { public Dog(String name) { super(name); } } public class ArrayDemo { public static void main(String[] args) { Animal[] animals = new Animal[2]; Cat cat = new Cat("little cat"); Dog dog = new Dog("little dog"); animals[0] = cat; animals[1] = dog; System.out.println(animals[0].name); System.out.println(animals[1].name); } }
這樣看上去,好像數組裏面存放了Cat類型和Dog類型,可是實際上他們都是Animal類型,數組裏面都是相同的類型,請你們不要搞混淆了,哈哈。spa
2.定義數組和初始化數組code
定義數組的語法格式:對象
type[] arrayName;
type arrayName[];
這兩種格式,我是強烈推薦第一種的,第一種格式給人很是的明確,定義了一個變量,它是type數組類型,可是第二種就可能給人一種假象,定義了一種變量,它是type類型的,爲了避免給別人誤會,仍是選擇第一種好點咯。
定義完了數組,這是內存中還沒給數組分配空間,真正分配內存空間的時候就是在給數組初始化的時候。blog
初始化數組分兩種:
靜態初始化:
arrayName = new type[]{element1,element2, element3......};
由上面很容易看出靜態的初始化就是顯式指定數組每一個元素的初始值,由系統決定數組的長度。
動態初始化:
arrayName = new type[length];
由上面看出動態初始化就是隻指定數組的長度,由系統爲數組分配初始值。
對於不一樣類型,系統分配的初始值也是不同的。
類型 |
初始值 |
整數類型(byte、short、int、long) |
0 |
浮點類型(float、double) |
0.0 |
字符類型(char) |
'\u0000'(表明空格) |
布爾類型(boolean) |
false |
引用類型(類、接口、數組) |
null |
你可能產生這樣的猜測:不是能夠同時使用靜態初始化和動態初始化嗎?
答案是不能夠的,編譯器是提示Cannot define dimension expressions when an array initializer is provided,由於你定義了長度,說明你已經初始化完了,我想一想也是以爲這樣不合理的,若是能夠二者混合使用的話,那麼我定義好了數組的長度後,系統是否是要給它附上默認的初始值,可是你後面又是靜態的初始化,指定了特定的值,系統又要爲你改變裏面的值,這樣作系統真累,我也以爲累。固然編譯器是不支持二者混合使用的,你們注意了!
3.數組的使用
數組的使用就是引用數組的索引,數組的索引是從0開始的,到length-1爲止,若是超過了這樣範圍就是拋出java.lang.ArrayIndexOutOfBoundException異常,就是數組索引越界異常,引用數組的使用太簡單了,下面就簡單用for和foreach來演示一下訪問:
public class ArrayDemo2 { public static void main(String[] args) { String[] strings = new String[]{"hello", "world"}; for(int i = 0; i < strings.length; i++) System.out.println(strings[i]); for(String string : strings) System.out.println(string); } }
4.內存中的數組:
type[] arrayName = new type[]{element1, element2, element3......};
arrayName就是一個引用的變量,這個數組的引用變量能夠指向任何有效的內存,只有當指向有效的內存後才能夠方位數組元素,能夠這麼說,引用變量是訪問真是對象的根本方式。
實際的數組對象被存儲在堆(heap)內存中,若是引用該數組獨享的數組引用變量是一個局部變量的話,那麼它被存儲在棧(stack)內存中,示意圖以下:
由這裏咱們能夠很清楚的看出局部數組引用變量是怎麼訪問到內存中的數組的,黨當一個方法調用完後,局部變量就沒了,也就是從棧內存中消失了,若是堆內存中數組再也不有任何引用變量指向本身,這個數組將成爲垃圾,該數組所佔的內存就會被系統的垃圾回收機制回收,所以,爲了讓垃圾回收機制回收一個數組所佔的內存空間,能夠將數組變量賦值爲null,也就切斷了數組引用變量和實際數組之間的關係,實際的數組也就成爲了垃圾。
在這裏,咱們讓一個引用變量指向另一個實際的數組的時候,可能產生數組長度可變的假象,你們來看看一個例子:
public class ArrayDemo3 { public static void main(String[] args) { int[] a = new int[]{1, 2}; int[] b = new int[4]; System.out.println("length of b:" + b.length); b = a; System.out.println("length of b:" + b.length); } }
結果:
length of b:4
length of b:2
從上面看咱們b數組的長度好像發生了變化,可是實際上不是這樣的,咱們來分析一下內存中的變化:
先是這樣:
而後這樣:
咱們所說的數組的長度不變是針對堆內存中真正數組的長度,引用變量是能夠改變指向的,指到哪裏確定就顯示指到的數組的長度了,可是真正的長度是未曾改變的。
5.操做數組的工具類:
Java提供的Arrays類裏包含的一些static修飾的方法能夠直接操做數組
int binarySearch(type[] a, type key):使用二分法查詢key元素值在a數組中出現的索引,若是a數組不包含key元素值,就返回負數,調用該方法的前提是數組中的元素已經按照升序排列好了。
type[] copyOf(type[] original, int newLength):這個方法能夠將original數組複製到一個新的數組,這個新的數組的長度爲newLength。
boolean equals(type[] a, type[] b):若是a數組和b數組的長度相等,並且數組中的元素一一相等,該方法就返回true。
void fill(type[] a, type val):該方法會將數組中的所有元素賦值爲val。
void sort(type[] a):該方法對a數組進行(升序)排序。