# 【數組】
##### 今日復習指南
~~~
1.簡化格式初始化數組的使用(0.5個小時內完成,多寫幾遍)
Demo01UseArray.java ? ?
? ?
2.數組的遍歷(0.5個小時內完成,多寫幾遍)
? ?Demo01ArrayEach.java
? ?
3.數組的最大值(1個小時,多寫幾遍)
? ?Demo03ArrayMax.java
~~~
##### 今日內容
~~~
數組的概念和數組變量的定義【重點】
數組的初始化及使用【重點的重點】 ---------------最核心的內容--------------
數組的內存圖【理解】
數組的常見問題【理解】
數組的練習【重點的重點】 ? ---------------最核心的內容--------------
? ?
快捷鍵:
? ?生產輸出語句: 表達式.sout
? ?數組遍歷:
? 數組名.fori: 正著遍歷
? 數組名.forr: 倒著遍歷
~~~
### 第一章 數組定義和訪問【理解】
##### 1.1 容器的概念
~~~
一個變量中只能存儲存儲一個數據,新的數據進來,老的數據被替換,如果要存儲多個數據,需要使用容器
?
容器:是將多個數據存儲到一起,每個數據稱為該容器的元素。
生活中的容器:水杯,衣柜,鞋柜, 教室
?
數組:
1.概念: java中的數組就是一個容器,可以存儲多個數據,但是這多個數據的類型必須保持一致
? ?2.特點:
? (1)可以存儲多個數據
? (2)多個數據的類型必須保持一致
? (3)數組長度一旦創建,永遠不可以發生改變
? ? ?
public class Demo01Box { //-----------------------此代碼不用敲--------------------------------
? ?public static void main(String[] args) {
? ? ? ?
? ? ? ?//比如我們班有80個學生需要參加考試,每個學生對應一個成績(整數)
? ? ? ?//可以定義80個int變量
? ? ? ?int a = 80;
? ? ? ?int b = 90;
? ? ? ?int c = 70;
? ? ? ?int d = 50;
? ? ? ?int e = 85;
? ? ? ?int f = 95;
? ? ? ?int g = 59;
? ? ? ?int h = 63;
?
? ? ? ?//需要求總分
? ? ? ?int sum = a + b + c + d + e + f + g + h;
?
? ? ? ?//需要求平均分
? ? ? ?int avg = sum/80;
?
? ? ? ?//需要求最高分和最低分: 實現起來非常麻煩
?
?
? }
}
? ? ? ? ?
~~~
##### 1.2 數組變量的定義
~~~
數組變量: 專門用來存儲數組容器的變量
?
1.數組變量定義格式一: 推薦使用的格式
數據類型[] 數組名稱1;
?
2.數組變量定義格式二: 不推薦使用的格式
數據類型 數組名稱[];
1.定義一個存儲int類型數組的變量arrayA
2.定義一個存儲double類型數組的變量arrayB
3.定義一個存儲char類型數組的變量arrayC
int[] arrayA: 這里只是定義了一個用來存儲數組容器的變量,相當于門牌 但是對應的教室現在/目前還沒有
? ? ? ?目前還沒有創建出真正的數組容器
~~~
~~~
public class Demo02Array {
? ?public static void main(String[] args) {
?
? ? ? ?//定義int變量num,未賦值
? ? ? ?int num;
? ? ? ?//System.out.println(num);//錯誤: 變量中沒有數據,不能使用
?
? ? ? ?//1.定義一個存儲int類型數組的變量arrayA
? ? ? ?//int類型數組: 該容器只能存儲int類型的數據
? ? ? ?int[] arrayA;
?
? ? ? ?//錯誤: 目前只是定義好了一個用來存儲數組容器的變量,但是還沒有向該變量中存儲數組呢
? ? ? ?//System.out.println(arrayA);
?
? ? ? ?//2.定義一個存儲double類型數組的變量arrayB
? ? ? ?//double類型數組: 該容器只能存儲double類型的數據
? ? ? ?double arrayB[];
?
? ? ? ?//3.定義一個存儲char類型數組的變量arrayC
? ? ? ?//char類型數組: 該容器只能存儲char類型的數據
? ? ? ?char[] arrayC;
?
?
? }
}
?
~~~
##### 圖解:

##### 1.3 數組的第一種初始化方式
~~~
數組的第一種初始化方式(動態初始化,指定數組的長度)
1.格式:
? 數據類型[] 數組名稱 = new 數據類型[長度];
?
? ?2.格式解釋:
? (1)左側數據類型: 表示數組容器中可以存儲什么類型的數據
? (2)左側[]: 表示數組的意思
? (3)數組名稱: 就是給數組起個名字,方便找到對應的數組
? (4)=: 把右側的數組容器存儲到左側的數組變量中
? =就是賦值,只是給數組變量賦的是數組容器在內存中的地址值
? (5)new: 在內存中創建數組容器的過程
? (6)右側數據類型: 和左側保持一致
? ? ? (7)長度: 數組中可以存儲多少個數據
?
3.練習:
(1)創建一個int類型的數組,可以存儲3個int數據,給該數組起個名稱叫做arrayA
? (2)創建一個double類型的數組,可以存儲7個double數據,給該數組起個名稱叫做arrayB
? (3)創建一個char類型的數組,可以存儲5個char數據,給該數組起個名稱叫做arrayC ? ? ?
?
~~~
~~~
public class Demo03Array {
? ?public static void main(String[] args) {
? ? ? ?//(1)創建一個int類型的數組,可以存儲3個int數據,給該數組起個名稱叫做arrayA
? ? ? ?int[] arrayA = new int[3];
?
? ? ? ?//(2)創建一個double類型的數組,可以存儲7個double數據,給該數組起個名稱叫做arrayB
? ? ? ?double[] arrayB = new double[7];
?
? ? ? ?//(3)創建一個char類型的數組,可以存儲5個char數據,給該數組起個名稱叫做arrayC
? ? ? ?char[] arrayC = new char[5];
?
?
? }
}
?
~~~
##### 1.4 數組的第二種初始化方式
~~~
數組的第二種初始化方式(標準格式靜態初始化: 指定數組元素)
1.格式:
? 數據類型[] 數組名稱 = new 數據類型[]{元素1,元素2,元素3...};
? ?2.注意: ?
(1){}中的多個元素之間用逗號隔開,最后一個元素后面沒有逗號
(2)右側[]中不用寫長度,JVM會根據{}中的元素數量,推導出長度
? ?3.練習:
? (1)創建一個int類型的數組,可以存儲多個int數據100,200,300,給該數組起個名稱叫做arrayA
? ? ? (2)創建一個double類型的數組,可以存儲多個double數據1.1,2.2,3.3,4.4,5.5,6.6,7.7,給該數組起個名稱叫做arrayB
? ? ? (3)創建一個char類型的數組,可以存儲多個char數據'真','的','好','想','你',給該數組起個名稱叫做arrayC
? ? ? ? ? ?
~~~
~~~
public class Demo04Array {
public static void main(String[] args) {
//(1)創建一個int類型的數組,可以存儲多個int數據100,200,300,給該數組起個名稱叫做arrayA
int[] arrayA = new int[]{100,200,300};
//(2)創建一個double類型的數組,可以存儲多個double數據1.1,2.2,3.3,4.4,5.5,6.6,7.7,給該數組起個名稱叫做arrayB
double[] arrayB = new double[]{1.1,2.2,3.3,4.4,5.5,6.6,7.7};
//(3)創建一個char類型的數組,可以存儲多個char數據'真','的','好','想','你',給該數組起個名稱叫做arrayC
char[] arrayC = new char[]{'真','的','好','想','你'};
}
}
~~~
##### 1.5 數組的第三種初始化方式
~~~
數組的第三種初始化方式(簡化格式的靜態初始化: 指定元素)
1.格式:
數據類型[] 數組名稱 = {元素1,元素2,元素3...};
2.練習:
(1)創建一個int類型的數組,可以存儲多個int數據100,200,300,給該數組起個名稱叫做arrayA
(2)創建一個double類型的數組,可以存儲多個double數據1.1,2.2,3.3,4.4,5.5,6.6,7.7,給該數組起個名稱叫做arrayB
(3)創建一個char類型的數組,可以存儲多個char數據'真','的','好','想','你',給該數組起個名稱叫做arrayC
3.注意:
(1){}中的多個元素之間用逗號隔開,最后一個元素后面沒有逗號
(2)不需要指定長度,JVM根據{}中元素的數量推導數組長度
(3)雖然沒有寫new,但是底層/內部仍然有new的過程
(4)對于動態初始化和標準格式的靜態初始化數組,可以分成兩步完成
(5)對于簡化格式靜態初始化方式,不可以分成兩步完成 java中的規定
~~~
~~~
public class Demo05Array {
public static void main(String[] args) {
//(1)創建一個int類型的數組,可以存儲多個int數據100,200,300,給該數組起個名稱叫做arrayA
int[] arrayA = {100, 200, 300};
//(2)創建一個double類型的數組,可以存儲多個double數據1.1,2.2,3.3,4.4,5.5,6.6,7.7,給該數組起個名稱叫做arrayB
double[] arrayB = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7};
//(3)創建一個char類型的數組,可以存儲多個char數據'真','的','好','想','你',給該數組起個名稱叫做arrayC
char[] arrayC = {'真', '的', '好', '想', '你'};
int a;
a = 10;
System.out.println(a);
a = 20;
System.out.println(a);
int[] array;//定義存儲一個int類型數組的變量array
array = new int[3];//把長度為3的int數組,存儲到變量array中
array = new int[]{10,20,30,50};//把存儲多個int數據的int數組,重新存儲到變量array中
int[] arr /*= {100,200,300,500}*/;
//arr = {100,200,300,500};//錯誤: java中規定,簡化格式靜態初始化數據進行賦值時,不能分成兩步完成
}
}
~~~
##### 1.6 數組的使用
~~~
/*
數組的使用 ============================================重點重點重點=========================================
1.數組名稱: 代表數組在內存中的地址值,是一個16進制的整數數字
2.索引編號: 是一個整數數字
(1)數組中的每個數據,稱之為數組元素
(2)數組為內部的每個元素進行了一個數字編號(整數數字),稱為索引/角標
索引從0開始到最大值(數組長度 減 1)
3.數組元素:
數組名稱[索引編號]
比如:
array[2]: 數組array中索引編號為2的元素
4.數組長度的獲取:
每個數組內部都有一個length屬性,保存數組用元素的個數
數組名稱.length: 是一個int數字,代表數組的長度
注意: length后面是沒有()的
*/
public class Demo01UseArray {
public static void main(String[] args) {
//int num = 10;
//System.out.println(num);//10
//創建int類型數組array,并初始化
int[] array = new int[]{100,200,300};//100的索引編號是0,200的索引編號是1,300的索引編號是2
//數組名稱: 代表數組在內存中的地址值,是一個16進制的整數數字
System.out.println(array);//[I@1540e19d
//打印100
System.out.println(array[0]);//打印數組array中索引編號為0的元素的值: 100
//打印200
System.out.println(array[1]);//打印數組array中索引編號為1的元素的值: 200
//打印300
System.out.println(array[2]);//打印數組array中索引編號為2的元素的值: 300
System.out.println("---------------");
//把100修改為1000
array[0] = 1000;//把數字1000存儲到array中索引編號為0的元素中
//把200修改為2000
array[1] = 2000;//把數字2000存儲到array中索引編號為1的元素中
//把300修改為3000
array[2] = 3000;//把數字3000存儲到array中索引編號為1的元素中
//打印1000
System.out.println(array[0]);//打印數組array中索引編號為0的元素的值: 1000
//打印2000
System.out.println(array[1]);//打印數組array中索引編號為1的元素的值: 2000
//打印3000
System.out.println(array[2]);//打印數組array中索引編號為2的元素的值: 3000
System.out.println("---------------");
//獲取數組array的長度,是一個int數字,保存到int變量count中
int count = array.length;
System.out.println("數組長度: "+count);
System.out.println("數組長度: "+array.length);
System.out.println("---------------");
/*
array.length的值: 3
打印數組元素,數組元素的所有格式: 數組名[索引編號]
array[array.length-1]: 先計算array.length-1 ==> 3 - 1 ==> 2
上面的式子等價于array[2]: 3000
*/
System.out.println(array[array.length-1]);//3000
}
}
~~~
### 第二章 數組原理內存圖【理解】
##### 2.1 java中的內存分配
~~~
1.方法區: 存儲可以運行的class文件。
2.方法棧: 方法運行時使用的內存,比如main方法運行,進入方法棧中執行。
3.堆內存 存儲對象或者數組,new來創建的,都存儲在堆內存。
4.寄存器 給CPU使用,和我們開發無關 不關心
5.本地方法棧 JVM在使用操作系統功能的時候使用,和我們開發無關。 不關心
今天主要使用:
1.棧內存: 運行方法的,存儲方法中定義的變量的
2.堆內存: 存儲的是所有new出來的內容
~~~
##### 圖解:

##### 2.2 一個數組內存圖
~~~
/*
一個數組的內存圖解
1.數組名稱: 數組在堆內存空間的地址值,16進制的整數數字
2.數組元素有默認值
(1)整數數組 0
(2)小數數組 0.0
(3)字符數組 空白字符
(4)布爾數組 false
(5)引用類型: null
3.注意:
(1)數組變量保存數組在堆內存中的地址值,通過地址值找到對應的數組
(2)數組元素都有索引編號,通過索引編號找到對應的元素
*/
public class Demo01OneArray {
public static void main(String[] args) {
//創建int類型數組one,長度為2
int[] one = new int[2];
System.out.println(one);//數組名稱: 數組在堆內存空間的地址值,16進制的整數數字: [I@1540e19d
System.out.println(one[0]);//打印數組one中索引編號0對應的元素的值,默認值:0
System.out.println(one[1]);//打印數組one中索引編號1對應的元素的值,默認值:0
//把索引編號0對應的元素修改成100
one[0] = 100;//把數字100存儲到數組one中索引編號為0的元素中
//把索引編號1對應的元素修改成200
one[1] = 200;//把數字200存儲到數組one中索引編號為1的元素中
System.out.println(one);//數組名稱: 數組在堆內存空間的地址值,16進制的整數數字: [I@1540e19d
System.out.println(one[0]);//打印數組one中索引編號0對應的元素的值:100
System.out.println(one[1]);//打印數組one中索引編號1對應的元素的值:200
}
}
~~~
##### 圖解:

##### 2.3 兩個數組內存圖
~~~
/*
兩個數組的內存圖解
1.數組名稱: 數組在堆內存空間的地址值,16進制的整數數字
2.注意:
(1)數組變量保存數組在堆內存中的地址值,通過地址值找到對應的數組
(2)數組元素都有索引編號,通過索引編號找到對應的元素
有兩個數組,相當有有兩套房子
一套是北京延慶兩居室的房子,one是打開北京延慶兩居室的房子的鑰匙
一套是北京平谷兩居室的房子,two是打開北京平谷兩居室的房子的鑰匙
你拿著鑰匙one: 只能打開北京延慶兩居室的房子
你的對象拿著鑰匙two: 只能打開北京平谷兩居室的房子
*/
public class Demo02TwoArray {
public static void main(String[] args) {
//創建int類型數組one,長度為2
int[] one = new int[2];//你在北京延慶購買了一套兩居室的房子,one就是打開這套房子的鑰匙
System.out.println(one);
System.out.println(one[0]);
System.out.println(one[1]);
one[0] = 100;
one[1] = 200;
System.out.println(one[0]);
System.out.println(one[1]);
System.out.println("--------------");
//創建int類型數組two,長度為2
int[] two = new int[2];//你在北京平谷購買了一套兩居室的房子,two就是打開這套房子的鑰匙
System.out.println(two);
System.out.println(two[0]);
System.out.println(two[1]);
two[0] = 1000;
two[1] = 2000;
System.out.println(two[0]);
System.out.println(two[1]);
}
}
~~~
##### 圖解:省略,就是把一個對象的內存圖復制兩份,每個數組之間沒有任何關系
##### 2.4 兩個變量指向一個數組
~~~
/*
一個數組兩個引用(名稱)的內存圖解
1.數組名稱: 數組在堆內存空間的地址值,16進制的整數數字
2.在使用數組名稱進行賦值時,傳遞的都是數組在內存空間的地址值
3.注意:
(1)數組變量保存數組在堆內存中的地址值,通過地址值找到對應的數組
(2)數組元素都有索引編號,通過索引編號找到對應的元素
數組變量名one中保存的是數組在堆內存空間的地址值,把one的值賦值給新的數組變量two,
導致數組變量名one和two保存相同的地址值,操作的是堆內存空間的同一個數組
one相當于是打開北京延慶兩居室的房子的鑰匙,現在通過鑰匙one又配了一個新的鑰匙two
此時: 鑰匙one和two打開的都是北京延慶兩居室的房子
鑰匙one: 你自己拿著
鑰匙two: 你對象拿著
注意:
1.數組變量保存數組在堆內存空間的地址值
2.使用數組變量進行賦值時,傳遞的是地址值
3.one保存數組在堆內存空間的地址值
把one賦值給新的數組變量two之后,
導致one和two保存相同的地址值,操作的
是同一個數組,不管通過one還是two修改
數組,之后再通過one和two看到的一定是
修改后的
*/
public class Demo03SameArray {
public static void main(String[] args) {
//創建int類型數組one,長度為2
int[] one = new int[2];//你在北京延慶購買了一套兩居室的房子,one就是打開這套房子的鑰匙
one[0] = 100;
/*
數組變量名one中保存的是數組在堆內存空間的地址值,把one的值賦值給新的數組變量two,
導致數組變量名one和two保存相同的地址值,操作的是堆內存空間的同一個數組
one相當于是打開北京延慶兩居室的房子的鑰匙,現在通過鑰匙one又配了一個新的鑰匙two
此時: 鑰匙one和two打開的都是北京延慶兩居室的房子
鑰匙one: 你自己拿著
鑰匙two: 你對象拿著
*/
int[] two = one;
two[0] = 1000;
System.out.println(one[0]);//1000
System.out.println(two[0]);//1000
System.out.println(one);//[I@1540e19d
System.out.println(two);//[I@1540e19d
}
}
~~~
##### 圖解:

### 第三章 數組操作的常見問題【了解】
##### 3.1 數組越界異常
~~~
數組操作的常見問題一:
數組索引越界(超出了范圍)異常
1.問題描述: java中使用java.lang.ArrayIndexOutOfBoundsException類來描述索引越界異常
2.產生原因:
使用int數字作為索引編號時,該索引編號在數組中是不存在的
索引編號范圍: 從0開始 到 最大值 ( 數組長度 減 1 one.length - 1 )
3.解決方案:
找到索引越界的數字,進行修改,不讓該數字超出數組元素的索引范圍
~~~
~~~
public class Demo01ArrayProblem {
public static void main(String[] args) {
//創建int數組one,并初始化
int[] one = new int[]{100, 200};//100編號是0,200的編號是1
System.out.println(one);//地址值: [I@1540e19d
System.out.println(one[0]);//100
System.out.println(one[1]);//200
//System.out.println(one[2]);//索引2不存在: 程序出現問題,停止了 報出數組索引越界異常
System.out.println("main...end...");
}
}
~~~
圖解:

##### 3.2 數組空指針異常
~~~
數組操作的常見問題二:
空指針異常
1.問題描述: java中使用java.lang.NullPointerException類來描述空指針異常
2.產生原因:
null是引用類型的空常量,可以賦值給任意引用類型的變量,一旦把null賦值給引用類型變量后,
說明該變量不再指向堆內存中的任何空間,也就不能操作堆內存空間的內容
null是引用類型的空常量,一旦把null賦值給數組變量后,
說明該數組變量不再指向堆內存空間中的任何數組,
也就不能再訪問數組元素了,只要訪問就會報出空指針異常
3.解決方案:
(1)找到引用變量是null的地方,進行修改,不讓它是null,讓它指向堆內存中的一個具體的數組
(2)不使用值為null的引用變量訪問堆內存空間的內容
~~~
~~~
public class Demo02ArrayProblem {
public static void main(String[] args) {
//創建int數組one,并初始化
int[] one = new int[]{100, 200};//100編號是0,200的編號是1
System.out.println(one);//地址值: [I@1540e19d
System.out.println(one[0]);//100
System.out.println(one[1]);//200
one = null;
System.out.println(one);//null
//System.out.println(one[0]);//one的值是null,不能訪問數組元素: 報出空指針異常
System.out.println("main...end...");
}
}
~~~
##### 圖解:

### 第四章 數組練習【重點】
##### 4.1 數組遍歷
~~~
數組遍歷:
就是將數組中的每個元素分別獲取出來,就是遍歷。遍歷也是數組操作中的基石。
public class Demo01ArrayEach {
public static void main(String[] args) {
//創建int數組array,并初始化
int[] array = {100, 200, 300};
System.out.println(array);//地址值
System.out.println(array[0]);//100
System.out.println(array[1]);//200
System.out.println(array[2]);//300
System.out.println("----------------");
//以上三行代碼重復,只有作為索引編號的數字0,1,2是不同的,可以使用for循環獲取作為索引編號的數字0,1,2
for (int i = 0; i < 3; i++) {
//System.out.println("索引編號: "+i+" 對應數組的元素值: "+array[i]);
System.out.println(array[i]);
}
System.out.println("----------------");
//以上for循環,數字3寫死了,其實數字3可以使用數組長度(數組名稱.length)代替
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
System.out.println("----------------");
for (int i = 0; i <= array.length - 1; i++) {
System.out.println(array[i]);
}
}
}
~~~
##### 4.2 求三個int數字的最大值
~~~
需求:
求三個int數字的最大值
實現步驟:
1.定義三個int變量a,b,c,并分別初始化
2.假設變量a的值是最大的,保存到int變量max中
3.判斷如果b的值 大于 max,說明max中已經不是最大的
3.1 把b的值賦值給max
4.判斷如果c的值 大于 max,說明max中已經不是最大的
4.1 把c的值賦值給max
5.打印max的值
public class Demo02VarMax {
public static void main(String[] args) {
//1.定義三個int變量a,b,c,并分別初始化
int a = 100, b = 200, c = 300;
//2.假設變量a的值是最大的,保存到int變量max中
int max = a;
//3.判斷如果b的值 大于 max,說明max中已經不是最大的
if(b > max) {
//3.1 把b的值賦值給max
max = b;
}
//4.判斷如果c的值 大于 max,說明max中已經不是最大的
if (c > max) {
//4.1 把c的值賦值給max
max = c;
}
//5.打印max的值
System.out.println("最大值: "+max);
}
}
~~~
圖解:

##### 4.3 數組獲取最大值元素
~~~
需求:
求int數組元素最大值
實現步驟:
1.創建int數組array,并初始化
2.假設索引為0的元素是最大的,保存到int變量max中
3.使用for循環依次獲取后面的(從索引1開始)每個元素
3.1如果當前元素值 大于 max 說明max中已經不是最大的了
3.2把當前元素賦值給max
4.for循環結束,打印max
~~~
~~~
public class Demo03ArrayMax {
public static void main(String[] args) {
//1.創建int數組array,并初始化
int[] array = {5, 15, 2000, 10000, 100, 4000};
//2.假設索引為0的元素是最大的,保存到int變量max中
int max = array[0];
//3.使用for循環依次獲取后面的(從索引1開始)每個元素
for (int i = 1; i < array.length; i++) {
//3.1如果當前元素值 大于 max 說明max中已經不是最大的了
if(array[i] > max) {
//3.2把當前元素賦值給max
max = array[i];
}
}
//4.for循環結束,打印max
System.out.println("數組元素最大值: "+max);
}
}
~~~
##### 圖解分析:

##### 執行流程:

##### 總結
~~~
能夠知道數組變量的定義格式
int[] array;
int array2[];
能夠使用兩種方式完成數組元素的初始化
1.動態初始化: 指定數組長度
int[] array = new int[3]
2.標準格式靜態初始化: 指定元素
int[] array = new int[]{10,20,30};
3.簡化格式靜態初始化: 指定元素
int[] array = {10,20,30};
能夠知道數組在內存中的初始化過程(了解)
能夠完成數組的遍歷操作
int[] array = {10,20,30};
for(int i = 0;i < array.length;i++) {
sout(array[i]);
}
for(int i = 0;i <= array.length-1;i++) {
sout(array[i]);
}
能夠完成數組的獲取最值操作
~~~