一.陣列的概念
1.陣列是Java里自帶的參考資料型別,是一個同一種資料型別的集合,陣列的構成有四大要素:陣列的資料型別,陣列的長度,陣列的陣列名,陣列的下標:語法如
int[] a;
a = new int[10]; String[] s = {"aaa","bbb","ccc"}; Student[] stu = new Student[10];
i.陣列的資料型別決定了這個陣列內能放陣列的型別,一個陣列不能存放有不同的陣列型別的資料
ii.陣列長度一旦定義下來了便無法更改
iii.陣列的名字是指向該陣列記憶體地址的
iv.陣列的下標是從0開始的
2.關于陣列的補充和些許演算法
i.遍歷陣列,for()回圈,從0下標到陣列.length-1下標一個一個找就好了,或者使用Stream.of()把它變成一個流,或者用別的方法如forEach()遍歷
ii.陣列的排序:
int a[] = {1,5,3,9,4,5}; //冒泡排序 for(int i =0;i < a.length-1;i++){ for(int j =0;j <a.length-i-1;j++){ if(a[j] > a[j+1]){ int temp = a[j]; a[j] = a[j+1]; a[j+1] = temp; } } } //選擇排序 for(int i = 0; i < a.length-1;i++){ for(int j = i+1; j < a.length;j++){ if(a[i] > a[j]{ int temp = a[j]; a[j] = a[i]; a[i] = temp; } } }
二.記憶體地址的基礎理解
1.在陣列里,對記憶體的理解:
i.當代碼運行至初始化一個陣列如int[] a = new int[5];此時記憶體便會在堆記憶體里開辟一個能存放長度為5的整數陣列的空間,而對陣列名,jvm會在堆疊記憶體中開辟一個空間存放該陣列名,而空間里的值則是一個指向堆內陣列空間的記憶體地 址
2.如上所說,jvm里有一個堆疊的記憶體空間,一個堆的記憶體空間,那么這兩個空間jvm到底會如何使用呢?
i.堆疊記憶體,也就是方法堆疊,每當jvm編譯運行一個方法時便會開辟一個方法堆疊幀,用來存放區域變數表,運算元堆疊,動態鏈接,方法出口等資訊,顯而易見該記憶體的存放資料的結構為堆疊,先進后出,這也是為什么區域變數會覆寫全域變數的原因,而在這個方法堆疊幀中,jvm每讀取一個基礎資料型別的變數名,都會把他存放在一個堆疊內,而里面存放的都是基礎資料型別變數,參考物件變數名,方法出口等資訊
ii.堆記憶體,這個記憶體是jvm管理的最大的記憶體空間,里面存放了參考資料型別的資料,如各種類的實體,各種陣列,各種介面
iii.堆疊內的參考物件變數名是怎么指向堆記憶體的實體的呢,那是因為堆疊內的每個參考物件變數名里存放的資料都是指向相應實體的記憶體地址
3.==和.equals()的區別
i.在Object類內其實.equals()和==沒區別,代碼如下:
public boolean equals(Object obj){ return (this == obj); }
所以說都是判斷兩方在堆疊記憶體中存放的資料
ii.那為什么說參考資料型別要用.equals()呢,如String之類
String a = new String ("aaa"); String b = new String ("aaa"); System.out.println(a == b); //輸出的是false
System.out.println(a.equals(b)); //輸出的是true
/*
那為什么會出現這種情況呢?不是說都是比較堆疊記憶體中存放的資料嗎?
那要回到上方的堆疊與堆內儲存資料的情況決議了,明顯堆疊記憶體放的兩個參考變數 a,b 指向的是不同的參考物件實體
而如果要比較他們的值 == 顯然不能排上用場,因為存放的是不同的記憶體地址,== 回傳的肯定是false,那為了解決這一情況java在常用類內如String 重寫了.equals()這一方法
使得其return的不是 this == obj 而是 this.value =https://www.cnblogs.com/Lzzycola/p/= obj.value
所以如果使用這種參考型別資料的時候請使用.equals()
我們下面再看另一種情況
*/
String c = "abc";
String d = "abc";
System.out.println( c == d); //這次輸出的是true
/*
那這次又是因為什么呢?
這要講一下jvm內的常量池空間,當給String 型別直接賦值一個字串 如"abc"這種,jvm就會自動在常量池內放一個值為"abc"的字串并把它認為是一個常量
而一個常量池內最多只能有一個相同的字串常量,那后來給d賦值"abc"時,jvm自動把d的記憶體地址指向了這個字串常量
因此這個時候 c d 兩個參考變數記憶體放的記憶體地址都是指向這個字串常量的,因此這個時候使用 == 兩個相同的記憶體地址比較 回傳的boolean值必然是 true
*/
4.對于方法內引數的傳遞
i.當jvm在一個方法堆疊幀內讀取到了另一個方法的出現,就會開辟另一個方法堆疊幀存放里面的新的資料,如區域變數表之類
ii.新的方法幀堆疊存放的資料由原方法幀堆疊傳遞而來所以就會出現下方的情況:
public static void main(String[] args){ int a = 0;
String s = "a";
int[] array = {1,5,3,6};
} public static void function(int a){ }
public static void function(String s){
}
public static void function(int[] array){
}
/*
顯然這三個方法傳遞的值都不同,一個是基礎資料型別,一個是String參考資料型別,一個是資料參考資料型別
由原方法堆疊幀到新方法堆疊幀內的資料轉移情況因引數傳遞的都是一個變數表內的值,但因為這兩種資料型別變數在表記憶體放的資料不同而產生了兩個不同的結果
1.基礎資料型別
新方法堆疊幀接受到了一個基礎資料型別的變數的值后會在自己的堆疊空間內新開辟一個與之相同的空間存放這個值,所以這個空間內無論這個值怎么變都不會影響到原方法堆疊幀內那個堆疊空間內的值
2.參考資料型別
新方法堆疊幀接收到了這個變數的值后也會做與接受基礎資料型別相同的操作,但因為這種變數存放的資料是指向一個物件實體的地址,所以新堆疊內的對這個資料的操作都會映射到那個儲存在堆內的物件實體,所以這里的操作會影響到實體資料的變化
*/
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/135877.html
標籤:Java
