Java中陣列的使用
- 1.陣列的基本用法
- 1.1一維陣列的使用
- 1.1.1一維陣列的宣告和初始化
- 1.1.2陣列元素的參考
- 1.1.3陣列元素的默認初始化值
- 1.1.4創建基本型別陣列
- 1.1.5初步認識Java虛擬機(JVM)
- 1.2二維陣列的使用
- 1.2.1二維陣列的初始化
- 1.2.3二維陣列的記憶體決議
- 3陣列中的常見操作
- 4.1陣列轉字串
- 4.2陣列拷貝
- 4.3查找陣列中的指定元素
- 4.3.1順序查找
- 4.3.2二分查找
- 4.4陣列排序(冒泡排序)
- 4.5陣列逆序
- 4.6陣列數字排列
- 4.陣列使用中的常見例外
1.陣列的基本用法
1.1一維陣列的使用
1.1.1一維陣列的宣告和初始化
一維陣列的宣告
宣告方式:
type var[] 或 type[] var;
例如:
int a[];
int[] a1;
double b[];
String[] c; //參考型別變數陣列
Java語言中宣告陣列時不能指定其長度(陣列中元素的數)
例如:
int a[5]; //非法
一維陣列的初始化
動態初始化:
陣列宣告且為陣列元素分配空間與賦值的操作分開進行
例如:
int[] arr = new int[3];
arr[0] = 6;
arr[1] = 1;
arr[2] = 1;
String names[];
names = new String[3];
names[0] = "錢學森";
names[1] = "鄧稼先";
names[2] = "袁隆平";
靜態初始化:
在定義陣列的同時就為陣列元素分配空間并賦值
例如:
int arr[] = new int[]{ 6, 1, 1};
//或者
int[] arr = {1,1,6};
String names[] = {"李四光","茅以升" ,"華羅庚"};
1.1.2陣列元素的參考
定義并用運算子new為之分配空間后,才可以參考陣列中的每個元素;
1.1.3陣列元素的默認初始化值
陣列是參考型別,它的元素相當于類的成員變數,因此陣列一經
分配空間,其中的每個元素也被按照成員變數同樣的方式被隱式
初始化,
例如:
public class Test {
public static void main(String argv[]){
int a[]= new int[5];
System.out.println(a[3]); //a[3]的默認值為0
}
}
//運行結果:
//0
注意:
- 對于基本資料型別而言,默認初始化值各有不同
- 對于參考資料型別而言,默認初始化值為null(注意與0不同!)
如下圖所示:

1.1.4創建基本型別陣列
Java中使用關鍵字new來創建陣列
例如:
public class Test{
public static void main(String args[]){
int[] s;//宣告
s = new int[10];//初始化
//也可以直接int[] s=new int[10];
//基本資料型別陣列在顯式賦值之前,Java會自動給他們賦默認值,
for ( int i=0; i<10; i++ ) {
s[i] =2*i+1;
System.out.println(s[i]);
}
}
一維陣列的結構圖:

記憶體的簡化結構

1.1.5初步認識Java虛擬機(JVM)
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 來呼叫的函式
1.2二維陣列的使用
1.2.1二維陣列的初始化
二維陣列[][]:陣列中的陣列
格式1(動態初始化) :
int[][] arr = new int[3][2];
// 定義了名稱為arr的二維陣列,
//二維陣列中有3個一維陣列
//每一個一維陣列中有2個元素
//一維陣列的名稱分別為arr[0], arr[1], arr[2]
//給第一個一維陣列1腳標位賦值為78寫法是:
arr[0][1] = 78;
格式2(動態初始化) :
int[][] arr = new int[3][];
//二維陣列中有3個一維陣列,
//每個一維陣列都是默認初始化值null (注意:區別于格式1)
//可以對這個三個一維陣列分別進行初始化
arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
//注:
int[][]arr = new int[][3]; //非法
格式3(靜態初始化) :
int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};
//定義一個名稱為arr的二維陣列,二維陣列中有三個一維陣列
//每一個一維陣列中具體元素也都已初始化
//第一個一維陣列 arr[0] = {3,8,2};
//第二個一維陣列 arr[1] = {2,7};
//第三個一維陣列 arr[2] = {9,0,1,6};
//第三個一維陣列的長度表示方式:
arr[2].length;
注意特殊寫法情況:
- int[] x,y[]; x是一維陣列,y是二維陣列
- Java中多維陣列不必都是規則矩陣形式
1.2.3二維陣列的記憶體決議
這部分我們通過結合代碼和圖來理解
如下代碼:
示例1:
int[][] arr = new int[3][];
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[4];
其存盤結構如下:

示例2:
int[][] arr1 = new int[4][];
arr1[1] = new int[]{1,2,3};
arr1[2] = new int[4];
arr1[2][1] = 30;
其記憶體結構圖為:

示例3
int[][] arr4 = new int[3][];
System.out.println(arr4[0]);//null
System.out.println(arr4[0][0]);//報錯
arr4[0] = new int[3];
arr4[0][1] = 5;
arr4[1] = new int[]{1,2};
其記憶體結構圖為:

3陣列中的常見操作
4.1陣列轉字串
import java.util.Arrays
int[] arr = {1,2,3,4,5,6};
String newArr = Arrays.toString(arr);
System.out.println(newArr);
// 執行結果 [1, 2, 3, 4, 5, 6]
Java 中提供了 java.util.Arrays 包, 其中包含了一些操作陣列的常用方法
實作一個自己版本的 toString
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6};
System.out.println(toString(arr));
}
public static String toString(int[] arr) {
String ret = "[";
for (int i = 0; i < arr.length; i++) {
// 借助 String += 進行拼接字串
ret += arr[i];
// 除了最后一個元素之外, 其他元素后面都要加上 ", "
if (i != arr.length - 1) {
ret += ", ";
}
}
ret += "]";
return ret;
}
4.2陣列拷貝
import java.util.Arrays
int[] arr = {1,2,3,4,5,6};
int[] newArr = Arrays.copyOf(arr, arr.length);
System.out.println("newArr: " + Arrays.toString(newArr));
arr[0] = 10;
System.out.println("arr: " + Arrays.toString(arr));
System.out.println("newArr: " + Arrays.toString(newArr)); // 拷貝某個范圍.
int[] newArr = Arrays.copyOfRange(arr, 2, 4);
System.out.println("newArr2: " + Arrays.toString(newArr2));
注意事項: 相比于 newArr = arr 這樣的賦值, copyOf 是將陣列進行了 深拷貝, 即又創建了一個陣列物件, 拷貝原有陣列中的所有元素到新陣列中. 因此, 修改原數組, 不會影響到新陣列
深拷貝:必須將物件也拷貝一份
淺拷貝:陣列內容是參考型別(地址),此時只能拷貝到地址,物件只是一個,依舊是修改同一個物件
拷貝的深淺要看拷貝物件,若為基本資料型別,則賦值就為深拷貝
實作自己版本的陣列拷貝:
public static int[] copyOf(int[] arr){
int[] ret = new int[arr.length];
for (int i = 0; i < arr.length; i++){
ret[i] = arr[i];
}
return ret;
}
4.3查找陣列中的指定元素
給定一個陣列, 再給定一個元素, 找出該元素在陣列中的位置.
4.3.1順序查找
public static void main(String[] args){
int[] arr = {1,2,3,10,5,6};
System.out.println(find(arr, 10));
}
public static int find(int[] arr, int toFind) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == toFind) {
return i;
}
}
return -1; // 表示沒有找到
}
// 執行結果 3
4.3.2二分查找
針對有序陣列, 可以使用更高效的二分查找
以升序陣列為例, 二分查找的思路是先取中間位置的元素, 看要找的值比中間元素大還是小. 如果小, 就去左邊找; 否則就去右邊找
public static void main(String[] args) {
int[] arr = {1,2,3,4,5,6};
System.out.println(binarySearch(arr, 6));
}
public static int binarySearch(int[] arr, int toFind) {
int left = 0;
int right = arr.length - 1;
while (left <= right){
int mid = (left + right) / 2;//取得中間元素
if (toFind < arr[mid]) { //去左側區間找
right = mid - 1;
} else if(toFind > arr[mid]){
//去右側區間找
left = mid + 1;
} else {
// 相等, 說明找到了
return mid;
}
}// 回圈結束, 說明沒找到
return -1;
}
// 執行結果 5
4.4陣列排序(冒泡排序)
public static void main(String[] args){
int[] arr = {9, 5, 2, 7};
bubbleSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void bubbleSort(int[] arr){
for (int i = 0; i < arr.length-1; i++){//趟數為長度-1
boolean flg = false;//每趟都會把flg重新置為false
for (int j=0; j<arr.length-1-i; j++){
if (arr[j - 1] > arr[j]){//檢查整體是不是升序
int tmp = arr[j - 1];//若不是,交換;若是跳過
arr[j - 1] = arr[j];
arr[j] = tmp;
flg = true;//交換后將flg改為true
}
}
if(flg==false){
break;//有序,沒有交換
}
} // end for
} // end bubbleSort
// 執行結果 [2, 5, 7, 9]
冒泡排序性能較低. Java 中內置了更高效的排序演算法
public static void main(String[] args){
int[] arr = {9, 5, 2, 7};
Arrays.sort(arr);//呼叫相應的排序演算法
System.out.println(Arrays.toString(arr));
}
4.5陣列逆序
給定一個陣列, 將里面的元素逆序排列.
思路:
設定兩個下標, 分別指向第一個元素和最后一個元素. 交換兩個位置的元素.
然后讓前一個下標自增, 后一個下標自減, 回圈繼續即可.
這里我們以將一個升序序列逆序為例:
public static void main(String[] args){
int[] arr = {1, 2, 3, 4};
reverse(arr);
System.out.println(Arrays.toString(arr));
}
public static void reverse(int[] arr){
int left = 0;//指向第一個元素
int right = arr.length - 1;//指向最后一個元素
while (left < right){//交換
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
4.6陣列數字排列
給定一個整型陣列, 將所有的偶數放在前半部分, 將所有的奇數放在陣列后半部分
例如
{1, 2, 3, 4}
調整后得到
{4, 2, 3, 1}
基本思路
設定兩個下標分別指向第一個元素和最后一個元素.用前一個下標從左往右找到第一個奇數, 用后一個下標從右往左找到第一個偶數, 然后交換兩個位置的元素.
依次回圈即可
public static void main(String[] args){
int[] arr = {1, 2, 3, 4, 5, 6};
transform(arr);
System.out.println(Arrays.toString(arr));
}
public static void transform(int[] arr) {
int left = 0;
int right = arr.length - 1;
while (left < right) {
// 該回圈結束, left 就指向了一個奇數
while (left < right && arr[left] % 2 == 0) {
left++;
}// 該回圈結束, right 就指向了一個偶數
while (left < right && arr[right] % 2 != 0) {
right--;
}// 交換兩個位置的元素
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
}
}
4.陣列使用中的常見例外

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/335543.html
標籤:java
