1. 程式人生 > 其它 >Java(5)陣列、二維陣列

Java(5)陣列、二維陣列

技術標籤:javajavase

目錄

一維陣列

一維陣列宣告

  • 陣列是引用資料型別;
  • 陣列值儲存在堆記憶體;
  • 陣列變數儲存在棧記憶體;
  • 棧記憶體中的陣列變數儲存的是一個引用。
int[] x;//規範,推薦使用這個
int x[];//也可
int []x;//也可

一維陣列初始化

靜態初始化
靜態初始化,需確定陣列長度和值

int[] array = new int[]{1,2,3,5,7,9,15}; //規範
int[] array = {1,2,3,4,5};

動態初始化
動態初始化,需確定陣列長度,陣列值為預設值

int[] array = new int[5];  //整型陣列的元素預設值為0
double[] array = new double[5];  //浮點型陣列的元素預設值為0.0
boolean[] array = new boolean[5];  //布林型陣列的元素預設值為false
char[] array = new char[5];  //字元型陣列的元素預設值為0對應的字元
引用型[] array = new 引用型[5];  //引用型陣列的元素預設值為null

陣列初始化過程:

  1. 在堆記憶體建立一塊連續的儲存區域,儲存區域的長度為給定的長度,堆記憶體中建立好的陣列的長度不可更改;
  2. 對於靜態初始化,把相應的值或引用複製給堆記憶體中陣列的各儲存單元;
  3. 對於動態初始化,堆記憶體中各儲存單元均為相應型別的預設值;
  4. 在棧記憶體中創建出陣列變數對應的儲存空間,用於儲存對堆記憶體中創建出的陣列的引用。
    注意事項
    如下程式碼:
public class Array{
	public static void main(String[] args){
		int[] array = new int[]{1,2,3,4,5};
		int a = array[0];
		int b = a;
		b[0] = 93;
		System.out.println(a[0]);
	}
}

上述程式碼打印出的a[0]值為93。因為陣列變數a把它的引用複製給了陣列變數b,那麼a和b值是對同一個陣列的引用,所以改變陣列b的第一個元素,陣列a的第一個元素也發生了相同的變化。

陣列訪問與遍歷

索引超出範圍時會產生執行時異常;
陣列變數有正常的for迴圈遍歷和加強的for迴圈遍歷。

public class Array{
	public static void main(String[] args){
		int[] array = new int[]{1,2,3,4,5};
		int a = array[0];  //訪問陣列第一個元素
		
		/*正常的for迴圈遍歷*/
		for(int index=0; index<5; index++){
			System.out.println(array[index]);
		}
		
		/*加強的for迴圈遍歷*/
		for(int e:array){
			System.out.println(e);
		}
	}
}

二維陣列

二維陣列宣告和初始化

public class Array{
	public static void main(String[] args){
		//宣告時初始化
		int[][] array = new int[][]{{},{1,2,3,4,5},{6,7,8},{9},{10}};
		
		//先初始化,再宣告
		int[][] array2;
		array2 = new int[][]{{},{1,2,3,4,5},{6,7,8},{9},{10}};

		//動態初始化
		int[][] array3 = new int[3][5];
	}
}

注意事項
對於上述程式碼:

  1. array[0]是對一個長度為0的陣列的引用,如果列印array[0],會顯示一串表示引用的字元;如果列印array[0]的第一個元素,會出現索引越界的執行時報錯。
  2. 二維陣列在記憶體中是樹的結構,而不是矩陣結構,列印array的五個陣列元素的長度會發現,它們並不一樣。
  3. 動態初始化二維陣列,第一個方括號內如果不填陣列,會編譯報錯;第二個方括號內如果不填數字,例如array3初始化的第二個數字"5"不填,那麼array3儲存的3個元素將是null,即3個空引用;如果把"5"換成"0",那麼array3儲存的三個元素分別是對3個長度為0的陣列的引用。
  4. 對於"5"不填的情形,可以對每一個值為null的元素初始化為相應的一維陣列,來使二維陣列充實起來。

二維陣列遍歷

public class Array{
	public static void main(String[] args){
		int[][] array = new int[][]{{1},{2,3},{4,5,6},{},{7,8,9,10}};
		/*普通for迴圈:*/
		for(int i=0; i<array.length; i++){
			int[] arr = array[i];
			for(int j=0; j<arr.length; j++){
				int value = arr[j];
				System.out.print(value+"\t");
			}
			System.out.println();
		}

		System.out.println("----------------分隔符------------------");

		/*增強for迴圈:*/
		for(int[] arr:array){
			for(int value:arr){
				System.out.print(value+"\t");
			}
			System.out.println();
		}
	}
}

上述程式碼執行結果為:
在這裡插入圖片描述

多維陣列儲存結構

多維陣列在記憶體中以樹的結構儲存,例如在堆記憶體中建立的若干一維陣列,把他們分成幾個小群體,每個小群體裡陣列的引用可以構成一個新的一維陣列,那麼這個新的陣列對於引用而言是一維陣列,對於引用的陣列的值而言,是二維陣列,若干個二維陣列的引用同樣可以構成新的陣列,新的陣列對於原始一維陣列的值而言就是三維陣列,更高維度的陣列以此類推。

小試牛刀

問題一:陣列a{1,2,3,4}與陣列b{5,6,7,8}互換

public class Array1{
	public static void main(String[] args){
		/*陣列a{1,2,3,4}與陣列b{5,6,7,8}互換*/
		int[] a = new int[]{1,2,3,4};
		int[] b = new int[]{5,6,7,8};
		
		/*方法一,中間變數法*/
		/*
		int[] c = a;
		a = b;
		b = c;
		*/

		/*方法二,逐個異或法*/
		for(int i=0; i<a.length; i++){
			a[i] = a[i]^b[i];
			b[i] = a[i]^b[i];
			a[i] = a[i]^b[i];
		}
		
		for(int i : a){System.out.print("陣列a:"+i+"\t");}
		System.out.println();
		for(int i : b){System.out.print("陣列b:"+i+"\t");}
	}
}

問題二:把陣列a{1,2,3,4,5,6}顛倒順序

public class Array1{
	public static void main(String[] args){
		/*把陣列a{1,2,3,4,5,6}顛倒順序*/
		int[] a = new int[]{1,2,3,4,5,6};
		for(int i=0; i<a.length/2 ; i++){
			a[i] = a[i]^a[a.length-i-1];
			a[a.length-i-1] = a[i]^a[a.length-i-1];
			a[i] = a[i]^a[a.length-i-1];
		}
		for(int i : a){System.out.print("陣列a:"+i+"\t");}
	}
}

問題三:去掉陣列a{1,0,0,7,17,0,23,31,-3,0,0,0}中非0元素

public class Array1{
	public static void main(String[] args){
		/*去掉陣列a{1,0,0,7,17,0,23,31,-3,0,0,0}中非0元素*/
		int[] a = new int[]{1,0,0,7,17,0,23,31,-3,0,0,0};
		int counter = 0;
		for(int i : a){if(i==0) counter++;}
		int[] b = new int[counter];
		int index = 0;
		for(int i : a){if(i!=0) b[index++] = i;}
		for(int i : b){System.out.print("陣列b:"+i+";");}
		a = null;//讓變數a成為空引用,那麼儲存在堆記憶體的原陣列a處於未被引用狀態,被視為垃圾,由垃圾回收機制回收。
	}
}

問題四:把1000以內的素數存到陣列a中

public class Array1{
	public static void main(String[] args){
		/*把1000以內的素數存到陣列a中*/
		int[] a = new int[500];
		int index = 0;
		for(int i=2; i<=1000; i++){
			if(i<4)a[index++] = i;
			else{
				boolean flag = true;
				for(int j=2; j<=Math.pow(i,0.5); j++){
					if(i%j==0){flag=false;break;}//改變flag並break以節省算力
				}
				if(flag) a[index++] = i;
			}
		}
		int[] b = new int[index];
		for(int i=0; i<index; i++) b[i] = a[i];
		a = null;
		for(int i : b){System.out.println(i+";");}
	}
}