文章目錄
(一)IDEA的基本配置&快捷鍵
(二)數組的概念
(三)數組的定義格式一:動態初始化
(四)數組的定義格式二:靜態初始化
(五)數組的定義格式三:省略的靜態初始化
(六)訪問數組元素進行獲取
(七)訪問數組元素進行賦值
(八)Java中的內存劃分
(九)一個數組的內存圖
(十)兩個數組的內存圖
(十一)兩個引用指向同一個數組的內存圖
(十二)常見問題:數組索引越界異常
(十三)常見問題:空指針異常
(十四)獲取數組的長度
(十五)數組的遍歷輸出
(十六)求出數組中的最值
(十七)數組元素反轉
(十八)數組作爲方法參數:傳遞地址
(十九)數組作爲方法返回值:返回地址
(一)IDEA的基本配置&快捷鍵
在IDEA工具中, Ctrl+空格 的快捷鍵,可以幫助我們補全代碼
但是這個快捷鍵和Windows中的輸入法切換快捷鍵衝突,需要修改IDEA中的快捷鍵
File->Settings->keymap->Main menu->code->Completion->Basic
Alt+/
跟其它快捷鍵衝突了,但是衝突的快捷鍵的功能我們用不上,所以直接Remove
效果如下:
其它的快捷鍵如下:
批量修改:shift+f6
,效果如下:
但是這種修改方式有三個缺點:
- 它只能修改當前文件
- 它不能選定範圍
- 它不能修改註釋裏面的字符
可以用以下方法解決以上兩個缺點,如下:
注意:可以直接使用快捷鍵ctrl+shift+r
(二)數組的概念
現在需要統計某公司員工的工資情況,例如計算平均工資、找到最高工資等。假設該公司有50名員工,用前面所學的知識,程序首先需要聲明50個變量來分別記住每位員工的工資,然後在進行操作,這樣做會顯得很麻煩,而且錯誤率也會很高。因此我們可以使用容器進行操作。將所有的數據全部存儲到一個容器中,統一操作。
- 容器:是將多個數據存儲到一起,每個數據稱爲該容器的元素
- 生活中的容器:水杯,衣櫃,教室
- 數組: 數組就是存儲數據長度固定的容器,保證多個數據的數據類型要一致
數組的特點:
- 數組是一種引用數據類型
- 數組當中的多個數據,類型必須統一
- 數組的長度在程序運行期間不可改變
兩種常見的初始化方式:
- 動態初始化(指定長度)
- 靜態初始化(指定內容)
(三)數組的定義格式一:動態初始化
動態初始化(指定長度):在創建數組的時候,直接指定數組當中的數據元素個數
格式:數據類型[] 數組名稱 = new 數據類型[數組長度];
解析含義:
- 左側數據類型:也就是數組當中保存的數據,全都是統一的什麼類型
- 左側的中括號:代表我是一個數組
- 左側數組名稱:給數組取一個名字
- 右側的new:代表創建數組的動作
- 右側數據類型:必須和左邊的數據類型保持一致
- 右側中括號的長度:也就是數組當中,到底可以保存多少個數據,是一個int數字
public class Demo01Array {
public static void main(String[] args) {
// 創建一個數組,裏面可以存放300個int數據
// 格式:數據類型[] 數組名稱 = new 數據類型[數組長度];
int[] arrayA = new int[300];
// 創建一個數組,能存放10個double類型的數據
double[] arrayB = new double[10];
// 創建一個數組,能存放5個字符串
String[] arrayC = new String[5];
}
}
(四)數組的定義格式二:靜態初始化
靜態初始化(指定內容):在創建數組的時候,不指定數據個數多少,而是指定具體的數據內容
格式:數據類型[] 數組名稱 = new 數據類型[] { 元素1, 元素2, ... };
注意:雖然靜態初始化沒有指定長度,但是根據大括號裏面的元素具體內容,可以自動推算出來長度
public class Demo02Array {
public static void main(String[] args) {
// 直接創建一個數組,裏面裝的全都是int數字,具體爲:5、15、25
int[] arrayA = new int[] { 5, 15, 25, 40 };
// 創建一個數組,用來裝字符串:"Hello"、"World"、"Java"
String[] arrayB = new String[] { "Hello", "World", "Java" };
}
}
(五)數組的定義格式三:省略的靜態初始化
標準格式:數據類型[] 數組名稱 = new 數據類型[] { 元素1, 元素2, ... };
省略格式:數據類型[] 數組名稱 = { 元素1, 元素2, ... };
注意事項:
- 靜態初始化沒有直接指定長度,但是仍然會自動推算得到長度
- 靜態初始化標準格式可以拆分成爲兩個步驟
- 動態初始化也可以拆分成爲兩個步驟
- 靜態初始化一旦使用省略格式,就不能拆分成爲兩個步驟了
使用建議:
- 如果不確定數組當中的具體內容,用動態初始化
- 如果已經確定了具體的內容,用靜態初始化
public class Demo03Array {
public static void main(String[] args) {
// 省略格式的靜態初始化
int[] arrayA = { 10, 20, 30 };
// 靜態初始化的標準格式,可以拆分成爲兩個步驟
int[] arrayB;
arrayB = new int[] { 11, 21, 31 };
// 動態初始化也可以拆分成爲兩個步驟
int[] arrayC;
arrayC = new int[5];
// 靜態初始化的省略格式,不能拆分成爲兩個步驟。
// int[] arrayD;
// arrayD = { 10, 20, 30 };
}
}
(六)訪問數組元素進行獲取
直接打印數組名稱,得到的是數組對應的:內存地址哈希值
訪問數組元素的格式:數組名稱[索引值]
索引值:就是一個int數字,代表數組當中元素的編號
注意:索引值從0開始,一直到“數組的長度-1”爲止
public class Demo04ArrayUse {
public static void main(String[] args) {
// 靜態初始化的省略格式
int[] array = { 10, 20, 30 };
System.out.println(array); // [I@75412c2f 其中[代表是數組、I代表是int類型
// 直接打印數組當中的元素
System.out.println(array[0]); // 10
System.out.println(array[1]); // 20
System.out.println(array[2]); // 30
System.out.println("=============");
// 也可以將數組當中的某一個單個元素,賦值交給變量
int num = array[1];
System.out.println(num); // 20
}
}
(七)訪問數組元素進行賦值
使用動態初始化數組的時候,其中的元素將會自動擁有一個默認值。規則如下:
如果是整數類型,那麼默認爲0
如果是浮點類型,那麼默認爲0.0
如果是字符類型,那麼默認爲'\u0000' \u是unicode編碼集的意思,0000是十六進制,是一個不可見的字符
如果是布爾類型,那麼默認爲false
如果是引用類型,那麼默認爲null
注意:靜態初始化也有默認值的過程,只是系統自動馬上將默認值替換成爲了大括號中的具體數值
public class Demo05ArrayUse {
public static void main(String[] args) {
// 動態初始化一個數組
int[] array = new int[3];
System.out.println(array); // 內存地址值
System.out.println(array[0]); // 0
System.out.println(array[1]); // 0
System.out.println(array[2]); // 0
System.out.println("=================");
// 將數據123賦值交給數組array當中的1號元素
array[1] = 123;
System.out.println(array[0]); // 0
System.out.println(array[1]); // 123
System.out.println(array[2]); // 0
}
}
(八)Java中的內存劃分
注意:.class相關信息(全局變量、方法、包括靜態相關的)全部都在方法區,如下:
(九)一個數組的內存圖
public static void main(String[] args) {
int[] array = new int[3]; // 動態初始化
System.out.println(array); // 地址值
System.out.println(array[0]); // 0
System.out.println(array[1]); // 0
System.out.println(array[2]); // 0
System.out.println("==============");
}
main方法是靜態方法,存放於方法區,是程序的入口,是第一個入棧的方法
array爲局部變量,要入棧
而數組是new出來的,所有new出來的東西都是存放在堆裏的
棧只是存放它的內存地址,我們之前的地址值是[I@xxx什麼的比較複雜,我們這裏假設是0x666
接着System.out.println(array);
方法入棧,打印出來的就是:0x666
其它方法也接着入棧,以array[0]爲例:先找到0x666地址,再到堆中找到第0個元素,如下:
下面對數組進行操作,如下:
public static void main(String[] args) {
int[] array = new int[3]; // 動態初始化
System.out.println(array); // 地址值
System.out.println(array[0]); // 0
System.out.println(array[1]); // 0
System.out.println(array[2]); // 0
System.out.println("==============");
// 改變數組當中元素的內容
array[1] = 10;
array[2] = 20;
System.out.println(array); // 地址值
System.out.println(array[0]); // 0
System.out.println(array[1]); // 10
System.out.println(array[2]); // 20
}
修改元素中的值,第一步也是先找到0x666地址,然後再到堆內存中找到相應的元素做修改
這裏同樣以array[0]爲例,如下:
(十)兩個數組的內存圖
public static void main(String[] args) {
int[] arrayA = new int[3];
System.out.println(arrayA); // 地址值
System.out.println(arrayA[0]); // 0
System.out.println(arrayA[1]); // 0
System.out.println(arrayA[2]); // 0
arrayA[1] = 10;
arrayA[2] = 20;
System.out.println(arrayA); // 地址值
System.out.println(arrayA[0]); // 0
System.out.println(arrayA[1]); // 10
System.out.println(arrayA[2]); // 20
int[] arrayB = new int[3];
System.out.println(arrayB); // 地址值
System.out.println(arrayB[0]); // 0
System.out.println(arrayB[1]); // 0
System.out.println(arrayB[2]); // 0
arrayB[1] = 100;
arrayB[2] = 200;
System.out.println(arrayB); // 地址值
System.out.println(arrayB[0]); // 0
System.out.println(arrayB[1]); // 100
System.out.println(arrayB[2]); // 200
}
(十一)兩個引用指向同一個數組的內存圖
public static void main(String[] args) {
int[] arrayA = new int[3];
System.out.println(arrayA); // 地址值
System.out.println(arrayA[0]); // 0
System.out.println(arrayA[1]); // 0
System.out.println(arrayA[2]); // 0
arrayA[1] = 10;
arrayA[2] = 20;
System.out.println(arrayA); // 地址值
System.out.println(arrayA[0]); // 0
System.out.println(arrayA[1]); // 10
System.out.println(arrayA[2]); // 20
// 將arrayA數組的地址值,賦值給arrayB數組
int[] arrayB = arrayA;
System.out.println(arrayB); // 地址值
System.out.println(arrayB[0]); // 0
System.out.println(arrayB[1]); // 10
System.out.println(arrayB[2]); // 20
arrayB[1] = 100;
arrayB[2] = 200;
System.out.println(arrayB); // 地址值
System.out.println(arrayB[0]); // 0
System.out.println(arrayB[1]); // 100
System.out.println(arrayB[2]); // 200
}
(十二)常見問題:數組索引越界異常
數組的索引編號從0開始,一直到"數組的長度-1"爲止
如果訪問數組元素的時候,索引編號並不存在,那麼將會發生
數組索引越界異常:ArrayIndexOutOfBoundsException
原因:索引編號寫錯了
解決:修改成爲存在的正確索引編號
public class Demo01ArrayIndex {
public static void main(String[] args) {
int[] array = { 15, 25, 35 };
System.out.println(array[0]); //15
System.out.println(array[1]); // 25
System.out.println(array[2]); // 35
// 錯誤寫法
// 並不存在3號元素,所以發生異常
System.out.println(array[3]);
}
}
(十三)常見問題:空指針異常
所有的引用類型變量,都可以賦值爲一個null值。但是代表其中什麼都沒有
數組必須進行new初始化才能使用其中的元素
如果只是賦值了一個null,沒有進行new創建,那麼將會發生空指針異常:NullPointerException
原因:忘了new
解決:補上new
public class Demo02ArrayNull {
public static void main(String[] args) {
int[] array = null;
// array = new int[3];
System.out.println(array[0]);
}
}
(十四)獲取數組的長度
如何獲取數組的長度,格式:數組名稱.length
這將會得到一個int數字,代表數組的長度
數組一旦創建,程序運行期間,長度不可改變
public class Demo03ArrayLength {
public static void main(String[] args) {
int[] arrayA = {10, 20, 30, 3, 5, 4, 6, 7, 8, 8, 65, 4, 44, 6, 10, 3, 5, 4, 6, 7, 8, 8, 65, 4};
int len = arrayA.length;
System.out.println("arrayB數組的長度是:" + len);
System.out.println("=============");
int[] arrayB = new int[3];
System.out.println(arrayB.length); // 3
arrayB = new int[5]; //此時arrayB已經指向新的數組了
System.out.println(arrayB.length); // 5
}
}
(十五)數組的遍歷輸出
遍歷數組:對數組當中的每一個元素進行逐一、挨個兒處理。默認的處理方式就是打印輸出
public class Demo04Array {
public static void main(String[] args) {
int[] array = { 15, 25, 30, 40, 50, 60, 75 };
// 首先使用原始方式
System.out.println(array[0]); // 15
System.out.println(array[1]); // 25
System.out.println(array[2]); // 30
System.out.println(array[3]); // 40
System.out.println(array[4]); // 50
System.out.println(array[5]); // 50
System.out.println("=================");
// 使用循環,次數其實就是數組的長度。
for (int i = 0; i < 6; i++) {
System.out.println(array[i]);
}
System.out.println("=================");
// int len = array.length; // 長度
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
注意:可以使用array.fori
快速生成遍歷代碼塊,類似於集合的iter
(十六)求出數組中的最值
public class Demo05ArrayMax {
public static void main(String[] args) {
int[] array = { 5, 15, 30, 20, 10000, 30, 35 };
int max = array[0]; // 比武擂臺
for (int i = 1; i < array.length; i++) {
// 如果當前元素,比max更大,則換人
if (array[i] > max) {
max = array[i];
}
}
// 誰最後最厲害,就能在max當中留下誰的戰鬥力
System.out.println("最大值:" + max);
}
}
public class Demo06ArrayMin {
public static void main(String[] args) {
int[] array = { 5, 15, 30, 20, 10000, -20, 30, 35 };
int min = array[0]; // 比武擂臺
for (int i = 1; i < array.length; i++) {
// 如果當前元素,比min更小,則換人
if (array[i] < min) {
min = array[i];
}
}
System.out.println("最小值:" + min);
}
}
(十七)數組元素反轉
數組元素的反轉:
本來的樣子:[1, 2, 3, 4]
之後的樣子:[4, 3, 2, 1]
要求不能使用新數組,就用原來的唯一一個數組
public class Demo07ArrayReverse {
public static void main(String[] args) {
int[] array = { 10, 20, 30, 40, 50 };
// 遍歷打印數組本來的樣子
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
System.out.println("============");
/*
初始化語句:int min = 0, max = array.length - 1
條件判斷:min < max
步進表達式:min++, max--
循環體:用第三個變量倒手
*/
for (int min = 0, max = array.length - 1; min < max; min++, max--) {
int temp = array[min];
array[min] = array[max];
array[max] = temp;
}
// 再次打印遍歷輸出數組後來的樣子
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
(十八)數組作爲方法參數:傳遞地址
當調用方法的時候,向方法的小括號進行傳參,傳遞進去的其實是數組的地址值
public class Demo01ArrayParam {
public static void main(String[] args) {
int[] array = { 10, 20, 30, 40, 50 };
System.out.println(array); // 地址值
printArray(array); // 傳遞進去的就是array當中保存的地址值
System.out.println("==========AAA==========");
printArray(array);
System.out.println("==========BBB==========");
printArray(array);
}
/*
三要素
返回值類型:只是進行打印而已,不需要進行計算,也沒有結果,用void
方法名稱:printArray
參數列表:必須給我數組,我才能打印其中的元素。int[] array
*/
public static void printArray(int[] array) {
System.out.println("printArray方法收到的參數是:");
System.out.println(array); // 地址值
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
(十九)數組作爲方法返回值:返回地址
一個方法可以有0、1、多個參數;但是隻能有0或者1個返回值,不能有多個返回值
如果希望一個方法當中產生了多個結果數據進行返回,怎麼辦?
解決方案:使用一個數組作爲返回值類型即可
任何數據類型都能作爲方法的參數類型,或者返回值類型
數組作爲方法的參數,傳遞進去的其實是數組的地址值
數組作爲方法的返回值,返回的其實也是數組的地址值
public class Demo02ArrayReturn {
public static void main(String[] args) {
int[] result = calculate(10, 20, 30);
System.out.println("main方法接收到的返回值數組是:");
System.out.println(result); // 地址值
System.out.println("總和:" + result[0]);
System.out.println("平均數:" + result[1]);
}
public static int[] calculate(int a, int b, int c) {
int sum = a + b + c; // 總和
int avg = sum / 3; // 平均數
// 兩個結果都希望進行返回
// 需要一個數組,也就是一個塑料兜,數組可以保存多個結果
/*
int[] array = new int[2];
array[0] = sum; // 總和
array[1] = avg; // 平均數
*/
int[] array = { sum, avg };
System.out.println("calculate方法內部數組是:");
System.out.println(array); // 地址值
return array;
}
}