Java 語言-4 Java 基礎語法 2.0
4.1 記憶體分析
- Java 記憶體簡單分析圖
- 簡單說明:
- 堆空間(heap):是不連續的空間,用於存放 new 出的物件,或者說是類的例項
- 棧空間(stack):連續的儲存空間,遵循後進先出的原則,用於存放區域性變數
- 方法區(method):方法區在堆空間內,用於存放:類的程式碼資訊、靜態變數和方法、常量池(字串常量等,具有共享機制)等等
4.2 陣列
4.2.1 簡單運用
-
簡單介紹
- 陣列是多個相同型別資料的有序集合的資料結構
- 每一個數據稱作一個數組元素,每個資料元素可以通過下標來訪問
-
宣告陣列的語法格式:
dataType[] arrayRefVar; //首選方法 dataType arrayRefVar[]; //非首選
方括號寫到變數名前面和後面效果相同
後者是跟C 和 C++ 相同的寫法
-
例如:宣告一維陣列
int[] a; doubule []b; Mydate []c;
-
-
建立陣列的語法格式:
dataType[] arrayRefVar = new dataType[arraySize];
-
例如:建立一維陣列
int []a = new int[3]; a[0] = 3; a[1] = 4; a[2] = 2; MySDate []dates = new MyDate[3]; dates[0] = new MyDate(22,7,1945); dates[1] = new MyDate(22,8,2022); dates[2] = new MyDate(2,12,2000);
-
-
宣告陣列時不能同時建立陣列(陣列中元素的個數)
- 例如:
int[5];
這是一個在 Java 的非法的宣告- 因為陣列是引用型別,這裡的 a(上面那個例子)只是一個引用
- 例如:
-
訪問:通過索引進行訪問,陣列索引從 0 開始
-
index 為陣列的下標,可以是整型常量或者整型表示式
- 例如:
a[1]
、b[i]
、c[6*i]
- 例如:
-
陣列元素的下標從 0 開始;長度為 n 的數組合法下標取值範圍:[0,n-1]
-
每一個數組都有一個屬性 length ,用於指明陣列長度,常用於迴圈
- 例如:
a.length
指明陣列 a 的長度
- 例如:
-
-
複製陣列
- 陣列複製的常用方法有 4 種
- for 迴圈,效率最低
- System.arraycopy() 效率最高
- Arrays.copyOf() 效率次於第二種方法
- Object.clone() 效率次於第二種和第三種
- 陣列複製的常用方法有 4 種
-
基本特點:
- 長度確定。陣列一旦被建立,大小就不可變
- 元素型別為相同型別,不允許出現混合型別
- 陣列的元素型別可以是任何資料型別,包括基本型別和引用型別
- 陣列變數屬於引用型別,陣列物件本身是在堆中
4.2.2 三種初始化
-
靜態初始化:在定義陣列的同時就為陣列元素分配空間並賦值
int[] a = {3,2,1}; //形式1 int[] a = new int[]{3,2,1}; //形式2 MyDate dates = { new MyDate(22,7,1945) };
int 例子中是兩種方式都可以使用
最後可用多寫一個逗號,如{3,2,1,}
-
動態初始化:在定義時分配空間和賦值分開進行
-
int[] a = new int[2]; a[0] = 1; a[1] = 2;
-
動態初始化也包括預設初始化
-
-
預設初始化:不進行賦值操作
- 因為陣列是引用型別,所以陣列一經分配空間,其中的每個元素也將按照成員變數同樣的方式被隱式初始化
- 數值型別是 0,引用型別是 null
- 例如:
int [] a = new int[5];
如果輸入a[3]
結果將是 0
- 因為陣列是引用型別,所以陣列一經分配空間,其中的每個元素也將按照成員變數同樣的方式被隱式初始化
4.2.3 陣列的使用
-
普通的 for 迴圈
-
For-Each 迴圈(增強 for 迴圈)
-
jdk1.5 以後的方法,沒有下標
-
示例:
package exercise; public class arrayFor { public static void main(String[] args) { int[] arrays = {1,23,4,45}; for (int array : arrays) { System.out.print(array); } } }
123445
-
快捷鍵呼叫:
陣列名.for
-
-
陣列作為引數
-
陣列作為返回值
4.2.4 多維陣列
-
多維陣列:可以認為是陣列的陣列,例如二維陣列就是一個特殊的一維陣列,每個元素就是一個一維陣列
-
例如:生成一個二維陣列
int[][] a = {{1,2},{3,4,0,9},{5,6,7}};
- 圖示:
- 圖示:
-
多維陣列的宣告初始化應按照從高維到低維的順序進行
-
例如:
int[][] t = new int [3][]; t[0] = new int[2]; t[1] = new int[3]; t[2] = new int[4]; …… int[][] x = new int [3][3];
-
不能寫為
int t1 [][] = new int [][4];
這與 C++ 不同
-
4.3 Arrays 類
-
陣列物件本身沒有提供什麼方法供其呼叫,而 API 提供了一個工具類 Arrays 來對陣列物件進行一些操作
- 陣列的工具類 java.util.Arrays
-
Arrays 的 方法都是通過 static 修飾的靜態方法,在使用時可以直接使用類名進行呼叫,而不通過使用物件來呼叫
-
常用功能:
方法 描述 fill() 陣列賦值 sort() 陣列升序排序 equals() 比較陣列中的元素是否相等 binarySearch() 對已經排序的陣列進行二分法查詢法 -
例如:使用 Arrays 排序再輸出
package exercise; import java.util.Arrays; public class arrayFor { public static void main(String[] args) { int[] a = {1,23,4,45}; Arrays.sort(a); System.out.println(Arrays.toString(a)); } }
[1, 4, 23, 45]
4.4 氣泡排序
-
氣泡排序是八大排序方法中可以說最出名的排序方法
-
實現方法:
- 兩層迴圈,外層冒泡輪數,裡層依次比較
-
示例程式碼:
package exercise; import java.util.Arrays; public class BubblingSort { public static void main(String[] args) { int[] a = {1,5,3,42,2,345,6}; int[] sort = sort(a); System.out.println(Arrays.toString(sort)); } public static int[] sort(int[] array){ int temp = 0; for (int i = 0; i < array.length-1; i++) { for (int j = 0; j < array.length-1-i; j++) { if (array[j+1]>array[j]){ temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } return array; } }
[345, 42, 6, 5, 3, 2, 1]
4.5 稀疏陣列
-
定義:稀疏陣列可以看做是普通陣列的壓縮,這裡普通陣列是指在需求資料中無效資料量遠大於有效資料量的陣列
-
例如:
的稀疏陣列為
-
-
用途:當一個數組大部分元素為 0,或者為同一值的陣列時,可以採用稀疏陣列來儲存該陣列
- 為什麼要儲存陣列
- 原陣列中存在大量的無效資料,佔據了大量的儲存空間,真正有用的資料卻少之又少
- 壓縮儲存可以節省儲存空間以避免資源的不必要的浪費,在資料序列化到磁碟時,壓縮儲存可以提高 I/O 效率
- 為什麼要儲存陣列
-
示例:將上面的例子用程式碼表示出來的一種方式
package exercise; import java.util.Arrays; public class SparceArrays { public static void main(String[] args) { //建立普通陣列 int[][] arrays1 = new int[11][11]; arrays1[1][2] = 1; arrays1[2][3] = 2; //列印普通陣列 System.out.println("原始陣列"); for (int[] ints : arrays1) { for (int anInt : ints) { System.out.print(anInt+"\t"); } System.out.println(); } //轉換為稀疏陣列 //獲取有效值的個數 int sum = 0; for (int i = 0; i < 11; i++) { for (int j = 0; j < 11; j++) { if (arrays1[i][j] != 0){ sum++; } } } System.out.println("有效值的個數:"+sum); //建立一個稀疏陣列 int[][] arrays2 = new int[sum+1][3]; arrays2[0][0] = 11; arrays2[0][1] = 11; arrays2[0][2] = sum; //遍歷普通陣列 int count = 0; for (int i = 0; i < arrays1.length; i++) { for (int j = 0; j < arrays1[i].length; j++) { if(arrays1[i][j] != 0){ count++; arrays2[count][0] = i; arrays2[count][1] = j; arrays2[count][2] = arrays1[i][j]; } } } //列印稀疏陣列 System.out.println("稀疏陣列"); for (int i=0; i<arrays2.length;i++) { System.out.println(arrays2[i][0]+"\t"+arrays2[i][1]+"\t"+arrays2[i][2]+"\t"); } //還原稀疏陣列 //1.讀取稀疏陣列 int[][] arrays3 = new int[arrays2[0][0]][arrays2[0][1]]; //2.還原原陣列 for (int i = 1; i < arrays2.length; i++) { arrays3[arrays2[i][0]][arrays2[i][1]] = arrays2[i][2]; } //輸出原始陣列 System.out.println("原始陣列"); for (int[] ints : arrays1) { for (int anInt : ints) { System.out.print(anInt+"\t"); } System.out.println(); } } }
執行結果:
原始陣列 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 有效值的個數:2 稀疏陣列 11 11 2 1 2 1 2 3 2 原始陣列 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0