
💜寫在前邊💜
前言
本篇博客主要講述了以下幾點問題
1. 理解陣列基本概念
2. 掌握陣列的基本用法
3. 陣列與方法互操作
4. 熟練掌握陣列相關的常見問題和代碼~
【?Java】淺談Java陣列的定義與使用
- 💜寫在前邊💜
- 🎄陣列基本用法
- 🎅什么是陣列
- 🎅創建陣列
- 🎅陣列的使用
- 🎄陣列作為方法的引數
- 🎅基本用法
- 🎅理解參考型別(敲黑板!!!)
- 🎅認識null
- 🎅 初時JVM記憶體區域劃分(敲黑板!!!)
- 🎅陣列作為方法的回傳值
- 🎄陣列練習
- 🎅二分查找
- 🎅冒泡排序
- 🎅判斷陣列是否有序
- 🎅只出現一次的元素
- 🎅改變原有陣列的值
- 🎅陣列所以元素之和
- 🎅 陣列拷貝
- 🎅陣列轉字串
- 🎅求陣列元素平均值
- 🎄二維陣列
🎄陣列基本用法
🎅什么是陣列
【陣列】本質上就是讓我們能 “批量” 創建相同型別的變數.
例如:
如果需要表示兩個資料, 那么直接創建兩個變數即可 int a; int b
如果需要表示五個資料, 那么可以創建五個變數 int a1; int a2; int a3; int a4; int a5;
但是如果需要表示一萬個資料, 那么就不能創建一萬個變數了. 這時候就需要使用陣列, 幫我們批量創建.
注意事項: 在 Java 中, 陣列中包含的變數必須是 相同型別.
🎅創建陣列
基本語法
動態初始化
資料型別[] 陣列名稱 = new 資料型別 [ ] { 初始化資料 };
如果在創建的同時不初始化陣列則必須指定其大小
資料型別[] 陣列名稱 = new 資料型別 [元素個數] ;
靜態初始化
資料型別[] 陣列名稱 = { 初始化資料 };
代碼示例
int[] arr = new int[]{1, 2, 3}; int[] arr = new int[3]; int[] arr = {1, 2, 3};
注意事項: 靜態初始化的時候, 陣列元素個數和初始化資料的格式是一致的.
其實陣列也可以寫成 int arr[] = {1, 2, 3};這樣就和 C 語言更相似了. 但是更推薦寫成 int[ ] arr 的形式. int和 [ ] 是一個整體.
🎅陣列的使用
代碼示例: 獲取長度 & 訪問元素
int[] arr = {1, 2, 3}; // 獲取陣列長度 System.out.println("length: " + arr.length); // 執行結果: 3 // 訪問陣列中的元素 System.out.println(arr[1]); // 執行結果: 2 System.out.println(arr[0]); // 執行結果: 1 arr[2] = 100; System.out.println(arr[2]); // 執行結果: 100
注意事項
1. 使用arr.length能夠獲取到陣列的長度【.】這個操作為成員訪問運算子. 后面在面向物件中會經常用到.
2. 使用 [ ] 按下標取陣列元素. 需要注意, 下標從 0 開始計數
3. 使用 [ ] 操作既能讀取資料, 也能修改資料.
4. 下標訪問操作不能超出有效范圍 [0, length - 1] , 如果超出有效范圍, 會出現下標越界例外
代碼示例: 下標越界
int[] arr = {1, 2, 3}; System.out.println(arr[100]); // 執行結果 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100 at Test.main(Test.java:4)拋出了
java.lang.ArrayIndexOutOfBoundsException例外. 使用陣列一定要下標謹防越界.
代碼示例: 遍歷陣列
所謂 “遍歷” 是指將陣列中的所有元素都訪問一遍, 不重不漏. 通常需要搭配回圈陳述句.int[] arr = {1, 2, 3}; for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } // 執行結果 1 2 3
代碼示例: 使用 for-each 遍歷陣列
int[] arr = {1, 2, 3}; for (int x : arr) { System.out.println(x); } // 執行結果 1 2 3for-each 是 for 回圈的另外一種使用方式. 能夠更方便的完成對陣列的遍歷. 可以避免回圈條件和更新陳述句寫錯.
🎄陣列作為方法的引數
🎅基本用法
代碼示例: 列印陣列內容
public static void main(String[] args) { int[] arr = {1, 2, 3}; printArray(arr); } public static void printArray(int[] a) { for (int x : a) { System.out.println(x); } } // 執行結果 1 2 3在這個代碼中
int[] a是函式的形參,int[] arr是函式實參.- 如果需要獲取到陣列長度, 同樣可以使用
a.length
🎅理解參考型別(敲黑板!!!)
我們知道Java是一門純面向物件的語言,我們在使用Java語言編程時,到處都在使用物件(《Thinking in Java》一書中提到"Everything is object")
程式在運行時,物件是在堆記憶體(heap)中存盤的,那么我們如何來訪問物件呢?在C/C++中是通過指標,而Java中是通過參考,參考儲存了物件在堆記憶體(heap)中的地址,
這里我們要先從記憶體開始說起.
如何理解記憶體?
記憶體就是指我們熟悉的 “記憶體”. 記憶體可以直觀的理解成一個宿舍樓. 有一個長長的大走廊, 上面有很多房間.每個房間的大小是 1 Byte (如果計算機有 8G 記憶體, 則相當于有 80億 個這樣的房間).
每個房間上面又有一個門牌號, 這個門牌號就稱為 地址
那么啥又是參考?
什么是參考?
參考相當于一個 “別名”, 也可以理解成一個指標.
創建一個參考只是相當于創建了一個很小的變數, 這個變數保存了一個整數, 這個整數表示記憶體中的一個地址.
請仔細看下圖(參考其實和指標很像)
參考與指標區別
(1)型別:
參考其值為地址的資料元素,Java封裝了的地址,可以轉換成字串查看,長度也可以不必擔心,
C指標是一個裝地址的變數,長度一般是計算機字長,可以認為是個int,
(2)所占記憶體:
參考宣告時沒有物體,不占空間,
C指標如果宣告之后會用到才會賦值,如果用不到不會分配記憶體,
(3)型別轉換:
參考的型別轉換,也可能不成功,運行時拋例外或者編譯就不能通過,
C指標指示個記憶體地址,指向記憶體,對程式來說還都是一個地址,但可能所指的地址不是程式想要的,
(4)初始值:
參考初始值為java關鍵字null,
C指標是int,如不初始化指標,那它的值就不是固定的了,這很危險,
(5)計算:
參考不可以計算,
C指標是int,他可以計算,如++或–,所以經常用指標來代替陣列下標,
(6)記憶體泄露:
Java參考不會產生記憶體泄露,
C指標是很容易產生記憶體泄露的,所以程式員要小心使用,及時回收,
🎅認識null
null 在 Java 中表示 “空參考” , 也就是一個無效的參考.
null 的作用類似于 C 語言中的 NULL (空指標), 都是表示一個無效的記憶體位置. 因此不能對這個記憶體進行任何讀寫操作. 一旦嘗試讀寫, 就會拋出 NullPointerException.
注意: Java 中并沒有約定 null 和 0 號地址的記憶體有任何關聯.
🎅 初時JVM記憶體區域劃分(敲黑板!!!)

- 程式計數器 (PC Register): 只是一個很小的空間, 保存下一條執行的指令的地址.
- 虛擬機堆疊(JVM Stack): 重點是存盤區域變數表(當然也有其他資訊). 我們剛才創建的 int[] arr 這樣的存盤地址的參考就是在這里保存.
- 本地方法堆疊(Native Method Stack): 本地方法堆疊與虛擬機堆疊的作用類似. 只不過保存的內容是Native方法的區域變數. 在有些版本的 JVM 實作中(例如HotSpot), 本地方法堆疊和虛擬機堆疊是一起的.
- 堆(Heap): JVM所管理的最大記憶體區域. 使用 new 創建的物件都是在堆上保存 (例如前面的 new int[]{1, 2, 3} )
- 方法區(Method Area): 用于存盤已被虛擬機加載的類資訊、常量、靜態變數、即時編譯器編譯后的代碼等資料. 方法編譯出的的位元組碼就是保存在這個區域.
- 運行時常量池(Runtime Constant Pool): 是方法區的一部分, 存放字面量(字串常量)與符號參考. (注意 從 JDK1.7 開始, 運行時常量池在堆上).
Native 本地方法:
JVM 是一個基于 C++ 實作的程式. 在 Java 程式執行程序中, 本質上也需要呼叫 C++ 提供的一些函式進行和作業系統底層進行一些互動. 因此在 Java 開發中也會呼叫到一些 C++ 實作的函式.
這里的 Native 方法就是指這些 C++ 實作的, 再由 Java 來呼叫的函式.
我們發現, 在上面的圖中, 程式計數器, 虛擬機堆疊, 本地方法堆疊被很多個基佬紫的, 名叫 Thread(執行緒) 的方框圈起來了,并且存在很多份. 而 堆, 方法區, 運行時常量池, 只有一份.
重點理解 虛擬機堆疊 和 堆.
- 區域變數和參考保存在堆疊上, new 出的物件保存在堆上.
- 堆的空間非常大, 堆疊的空間比較小.
- 堆是整個 JVM 共享一個, 而堆疊每個執行緒具有一份(一個 Java 程式中可能存在多個堆疊).
🎅陣列作為方法的回傳值
代碼示例: 寫一個方法, 將陣列中的每個元素都 * 2
// 直接修改原陣列 class Test { public static void main(String[] args) { int[] arr = {1, 2, 3}; transform(arr); printArray(arr); } public static void printArray(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } public static void transform(int[] arr) { for (int i = 0; i < arr.length; i++) { arr[i] = arr[i] * 2; } } }這個代碼固然可行, 但是破壞了原有陣列. 有時候我們不希望破壞原陣列, 就需要在方法內部創建一個新的陣列, 并由方法回傳出來.
// 回傳一個新的陣列 class Test { public static void main(String[] args) { int[] arr = {1, 2, 3}; int[] output = transform(arr); printArray(output); } public static void printArray(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } public static int[] transform(int[] arr) { int[] ret = new int[arr.length]; for (int i = 0; i < arr.length; i++) { ret[i] = arr[i] * 2; } return ret; } }這樣的話就不會破壞原有陣列了.
另外由于陣列是參考型別, 回傳的時候只是將這個陣列的首地址回傳給函式呼叫者, 沒有拷貝陣列內容, 從而比較高效.
🎄陣列練習
🎅二分查找
public class 二分查找 {
public static int binarySearch(int []arr, int target) {
int left = 0;
int right = arr.length-1;
while (left <= right) {
int mid=(left+right)/2;
if (arr[mid]<target){
left = mid+1;
}
else if (arr[mid]>target){
right = mid-1;
}
else
return mid+1;
}
System.out.println("沒有這個數");
return -1;
}
public static void main(String[] args) {
int target = 8;
int arr[] = {1,2,3,4,5,6,7,8};
System.out.println("要查找的數是第"+binarySearch(arr,target)+"個");
}
}
🎅冒泡排序
import java.util.Arrays;
public class 冒泡排序 {
public static int[] bubble(int arr[]) {
for (int i = 0; i < arr.length-1; i++){
for (int j = 0; j < arr.length-1-i; j++){
if (arr[j]>arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
public static void main(String[] args) {
int arr [] = {1,1,4,7,2,4,6,9,2,6,5};
System.out.println(Arrays.toString(bubble(arr)));
}
}
🎅判斷陣列是否有序
public class 判斷陣列是否有序 {
public static boolean judgment(int arr[]) {
for (int i = 0; (i+1)<arr.length; i++){
if (arr[i]>arr[i+1])
return false;
}
return true;
}
public static void main(String[] args) {
int arr1[] = {1,2,3,4};
int arr2[] = {2,1,4,3};
if (judgment(arr1))
System.out.println("arr1"+"有序");
else
System.out.println("arr1"+"無序");
if (judgment(arr2))
System.out.println("arr2"+"有序");
else
System.out.println("arr2"+"無序");
}
}
🎅只出現一次的元素
public class 只出現一次的數字 {
public static int Only(int arr[]) {
int tmp = 0;
for (int i = 0; i < arr.length; i++) {
/*
涉及到異或運算,對于這道題,你應該了解異或有什么樣性質
1. 任何數與0異或,都為原數
2. 與本身自己異或,則為0
3. 交換律和結合律(解決這道題的關鍵),你把整個回圈的計算寫成數學運算程序,你會發現要利用交換律和結合律,可以實作這道題的要求
*/
tmp ^= arr[i];
}
return tmp;
}
public static void main(String[] args) {
int arr[] = {2,0,0,1,1,2,6};
System.out.println(Only(arr));
}
}
🎅改變原有陣列的值
import java.util.*;
public class 改變原有陣列元素的值 {
public static int[] transform(int[]array2) {
for (int i = 0; i < array2.length; i++) {
array2[i] *=2;
}
return array2;
}
public static void main(String[] args) {
int [] array1 = {1,2,3,};
System.out.println(Arrays.toString(array1));
System.out.println("×2改變之后陣列="+ Arrays.toString(transform(array1)));
}
}
🎅陣列所以元素之和
public class 陣列所有元素之和 {
public static float sum(int[]array) {
int sum = 0;
for (int i = 0; i < array.length; i++)
sum += array[i];
return sum;
}
public static void main(String[] args) {
int [] array = {1,2,3,};
for (int i = 0; i < array.length; i++)
System.out.print(array[i]+" ");
System.out.println();
System.out.println("所以元素之和="+sum(array));
}
}
🎅 陣列拷貝
import java.util.Arrays;
public class 陣列的拷貝 {
public static int[] copyOf(int []arr1) {
int []arr2;
arr2 = new int[arr1.length];
for (int i = 0; i < arr1.length; i++) {
arr2[i] = arr1[i];
}
return arr2;
}
public static void main(String[] args) {
int []arr1={1,2,3,4,5};
System.out.println("arr1="+Arrays.toString(arr1));
System.out.println("arr2="+Arrays.toString(copyOf(arr1)));
}
}
🎅陣列轉字串
public class 陣列轉字串 {
public static void printString(int[]arr) {
String a ="[";
for (int i = 0; i < arr.length; i++){
a+=arr[i];
if(i != arr.length -1)
a += ",";
}
a+="]";
System.out.println(a);
}
public static void main(String[] args) {
int arr[] = {1,2,3,4,5};
printString(arr);
}
}
🎅求陣列元素平均值
public class 求陣列的平均值 {
public static float avg(int[]array) {
float avg;
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
}
avg = sum / array.length;
return avg;
}
public static void main(String[] args) {
int [] array = {1,2,3,};
for (int i = 0; i < array.length; i++)
System.out.print(array[i]+" ");
System.out.println();
System.out.println("平均數="+avg(array));
}
}
🎄二維陣列
二維陣列本質上也就是一維陣列, 只不過每個元素又是一個一維陣列.
基本語法
資料型別[][] 陣列名稱 = new 資料型別 [行數][列數] { 初始化資料 };
代碼示例
二維陣列的用法和一維陣列并沒有明顯差別, 因此我們不再贅述.
不過要注意一個點,C里每行陣列會跟列對齊,會自動補0,java里不會自動補,如下代碼import java.util.Arrays; public class test { public static void main(String[] args) { int[][] arr; arr = new int[][]{ {1, 2, 3}, {5, 6, 7, 8}, {9, 10, 11, 12} }; for (int row = 0; row < arr.length; row++) { for (int col = 0; col < arr[row].length; col++) { System.out.printf("%d\t", arr[row][col]); } System.out.println(""); }// 執行結果 // 1 2 3 // 5 6 7 8 // 9 10 11 12 } }
🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙
?原創不易,如有錯誤,歡迎評論區留言指出,感激不盡?
? 如果覺得內容不錯,給個三連不過分吧~ ?
? 看到會回訪~ ?
🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙🌙
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/340609.html
標籤:其他
上一篇:TCP回顯程式中的小細節


