【基礎模塊】java數組深層理解(原理

數組定義和訪問

容器概述

案例分析

現在需要統計某公司員工的工資情況,例如計算平均工資、找到最高工資等。假設該公司有50名員工,用前面所學的知識,程序首先需要聲明50個變量來分別記住每位員工的工資,然後在進行操作,這樣做會顯得很麻煩,而且錯誤率也會很高。因此我們可以使用容器進行操作。將所有的數據全部存儲到一個容器中,統一操作。

容器概念

容器:是將多個數據存儲到一起,每個數據稱為該容器的元素

生活中的容器:水杯,衣櫃,教室

數組概念: 數組就是存儲數據長度固定的容器,保證多個數據的數據類型要一致。

數組的定義

方式一

<code>數組存儲的數據類型[] 數組名字 = 

new

數組存儲的數據類型[長度];/<code>

數組定義格式詳解:

數組存儲的數據類型: 創建的數組容器可以存儲什麼數據類型。

[] : 表示數組。

數組名字:為定義的數組起個變量名,滿足標識符規範,可以使用名字操作數組。

new:關鍵字,創建數組使用的關鍵字。

數組存儲的數據類型: 創建的數組容器可以存儲什麼數據類型。

[長度]:數組的長度,表示數組容器中可以存儲多少個元素。

注意:數組有定長特性,長度一旦指定,不可更改。

和水杯道理相同,買了一個2升的水杯,總容量就是2升,不能多也不能少。

eg:定義可以存儲3個整數的數組容器,代碼如下:

<code>

int

[] arr =

new

int

[

3

];/<code>

方式二

<code>數據類型[] 數組名 = 

new

數據類型[]{元素

1

,元素

2

,元素

3.

..};/<code>

eg:定義存儲1,2,3,4,5整數的數組容器。

<code>

int

[] arr =

new

int

[]{

1

,

2

,

3

,

4

,

5

};/<code>

方式三

<code>數據類型[] 數組名 = {元素1,元素2,元素3...};/<code>

eg:定義存儲1,2,3,4,5整數的數組容器

<code>

int

[] arr = {

1

,

2

,

3

,

4

,

5

};/<code>

數組的訪問

索引: 每一個存儲到數組的元素,都會自動的擁有一個編號,從0開始,這個自動編號稱為數組索引

(index),可以通過數組的索引訪問到數組中的元素。

訪問方式:

<code>數組名

[索引]

/<code>

數組的長度屬性: 每個數組都具有長度,而且是固定的,Java中賦予了數組的一個屬性,可以獲取到數組的長度,語句為: 數組名.length ,屬性length的執行結果是數組的長度,int類型結果。由次可以推斷出,數組的最大索引值為 數組名.length-1

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr =

new

int

[]{

1

,

2

,

3

,

4

,

5

}; System.

out

.println(arr.length); }/<code>

索引訪問數組中的元素:

數組名[索引]=數值,為數組中的元素賦值

變量=數組名[索引],獲取出數組中的元素

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr = {

1

,

2

,

3

,

4

,

5

}; arr[

0

] =

6

;

int

i = arr[

0

]; System.

out

.println(i); System.

out

.println(arr[

0

]); }/<code>

數組原理內存圖

內存概述:內存是計算機中的重要原件,臨時存儲區域,作用是運行程序。我們編寫的程序是存放在硬盤中的,在硬盤中的程序是不會運行的,必須放進內存中才能運行,運行完畢後會清空內存。

Java虛擬機要運行程序,必須要對內存進行空間的分配和管理

Java虛擬機的內存劃分

為了提高運算效率,就對空間進行了不同區域的劃分,因為每一片區域都有特定的處理數據方式和內存管理方式。

JVM的內存劃分:


【基礎模塊】java數組深層理解(原理/使用/jvm內存)

jvm內存劃分

一個數組內存圖

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr =

new

int

[

3

]; System.

out

.println(arr); }/<code>

以上方法執行,輸出的結果是[I@5f150435,這個是什麼呢?是數組在內存中的地址。new出來的內容,都是在堆內存中存儲的,而方法中的變量arr保存的是數組的地址。

輸出arr[0],就會輸出arr保存的內存地址中數組中0索引上的元素


【基礎模塊】java數組深層理解(原理/使用/jvm內存)

兩個數組內存圖

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr =

new

int

[

3

];

int

[] arr2 =

new

int

[

2

]; System.

out

.println(arr); System.

out

.println(arr2); }/<code>


【基礎模塊】java數組深層理解(原理/使用/jvm內存)

兩個變量指向一個數組

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr =

new

int

[

3

]; arr[

0

] =

5

; arr[

1

] =

6

; arr[

2

] =

7

; System.

out

.println(arr[

0

]); System.

out

.println(arr[

1

]); System.

out

.println(arr[

2

]);

int

[] arr2 = arr; arr2[

1

] =

9

; System.

out

.println(arr[

1

]); }/<code>


【基礎模塊】java數組深層理解(原理/使用/jvm內存)

數組的常見操作和異常處理

數組越界異常

觀察一下代碼,運行後會出現什麼結果。

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr = {

1

,

2

,

3

}; System.

out

.println(arr[

3

]); }/<code>

創建數組,賦值3個元素,數組的索引就是0,1,2,沒有3索引,因此我們不能訪問數組中不存在的索引,程序運行後,將會拋出
ArrayIndexOutOfBoundsException 數組越界異常。在開發中,數組的越界異常是不能出現的,一旦出現了,就必須要修改我們編寫的代碼。

數組空指針異常

觀察一下代碼,運行後會出現什麼結果。

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr = {

1

,

2

,

3

}; arr =

null

; System.

out

.println(arr[

0

]); }/<code>

arr = null 這行代碼,意味著變量arr將不會在保存數組的內存地址,也就不允許再操作數組了,因此運行的時候會拋出 NullPointerException 空指針異常。在開發中,數組的空指針異常是不能出現的,一旦出現了,就必須要修改我們編寫的代碼。

【基礎模塊】java數組深層理解(原理/使用/jvm內存)

空指針異常在內存圖中的表現

數組遍歷【重點】

數組遍歷: 就是將數組中的每個元素分別獲取出來,就是遍歷。遍歷也是數組操作中的基石。

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr = {

1

,

2

,

3

,

4

,

5

}; System.

out

.println(arr[

0

]); System.

out

.println(arr[

1

]); System.

out

.println(arr[

2

]); System.

out

.println(arr[

3

]); System.

out

.println(arr[

4

]); }/<code>

以上代碼是可以將數組中每個元素全部遍歷出來,但是如果數組元素非常多,這種寫法肯定不行,因此我們需要改造成循環的寫法。數組的索引是 0 到 lenght-1 ,可以作為循環的條件出現。

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr = {

1

,

2

,

3

,

4

,

5

};

for

(

int

i =

0

; i
< arr.length; i++) { System.

out

.println(arr[i]); } }/<code>

數組獲取最大值元素

最大值獲取:從數組的所有元素中找出最大值。

實現思路:

定義變量,保存數組0索引上的元素

遍歷數組,獲取出數組中的每個元素

將遍歷到的元素和保存數組0索引上值的變量進行比較

如果數組元素的值大於了變量的值,變量記錄住新的值

數組循環遍歷結束,變量保存的就是數組中的最大值


【基礎模塊】java數組深層理解(原理/使用/jvm內存)

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr = {

5

,

15

,

2000

,

10000

,

100

,

4000

};

int

max = arr[

0

];

for

(

int

i =

0

; i < arr.length; i++) {

if

(arr[i] > max) { max = arr[i]; } } System.

out

.println(

"數組最大值是: "

+ max); }/<code>

數組反轉

數組的反轉: 數組中的元素顛倒順序,例如原始數組為1,2,3,4,5,反轉後的數組為5,4,3,2,1

實現思想:數組最遠端的元素互換位置。

實現反轉,就需要將數組最遠端元素位置交換

定義兩個變量,保存數組的最小索引和最大索引

兩個索引上的元素交換位置

最小索引++,最大索引--,再次交換位置

最小索引超過了最大索引,數組反轉操作結束


【基礎模塊】java數組深層理解(原理/使用/jvm內存)

<code>

public

static

void main(

String

[] args) { int[] arr = {

1

,

2

,

3

,

4

,

5

};

for

(int

min

=

0

,

max

= arr.length ‐

1

;

min

<=

max

;

min

++,

max

‐‐) { int temp = arr[

min

]; arr[

min

] = arr[

max

]; arr[

max

] = temp; }

for

(int i =

0

; i
< arr.length; i++) {

System

.out.

println

(arr[i]); } }/<code>

數組作為方法參數和返回值

以前的方法中我們學習了方法的參數和返回值,但是使用的都是基本數據類型。那麼作為引用類型的數組能否作為方法的參數進行傳遞呢,當然是可以的。

數組作為方法參數傳遞,傳遞的參數是數組內存的地址。

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr = {

1

,

3

,

5

,

7

,

9

}; printArray(arr); }

public

static

void

printArray

(

int

[] arr

)

{

for

(

int

i =

0

; i < arr.length; i++) { System.

out

.println(arr[i]); } }/<code>


【基礎模塊】java數組深層理解(原理/使用/jvm內存)

數組作為方法返回值

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr = getArray();

for

(

int

i =

0

; i < arr.length; i++) { System.

out

.println(arr[i]); } }

public

static

int

[]

getArray

(

)

{

int

[] arr = {

1

,

3

,

5

,

7

,

9

};

return

arr; }/<code>


【基礎模塊】java數組深層理解(原理/使用/jvm內存)

方法的參數類型區別

分析下列程序代碼,計算輸出結果。

<code>

public

static

void

main

(

String[] args

)

{

int

a =

1

;

int

b =

2

; System.

out

.println(a); System.

out

.println(b); change(a, b); System.

out

.println(a); System.

out

.println(b); }

public

static

void

change

(

int

a,

int

b

)

{ a = a + b; b = b + a; }/<code>

分析下列程序代碼,計算輸出結果

<code>

public

static

void

main

(

String[] args

)

{

int

[] arr = {

1

,

3

,

5

}; System.

out

.println(arr[

0

]); change(arr); System.

out

.println(arr[

0

]); }

public

static

void

change

(

int

[] arr

)

{ arr[

0

] =

200

; }/<code>

總結:

方法的參數為基本類型時,傳遞的是數據值. 方法的參數為引用類型時,傳遞的是地址值.


分享到:


相關文章: