一圃验、數(shù)組簡介
概念:是一種容器,可以同時存放多個數(shù)據(jù)值缝呕。
數(shù)組的特點:
- 數(shù)組是一種引用數(shù)據(jù)類型
- 數(shù)組當中的多個數(shù)據(jù)澳窑,類型必須統(tǒng)一(或者是當前類型的子類,例如:Object[]可以存放任意的數(shù)組類型供常,因為java中所有的類都是Object的子類)
- 數(shù)組的長度在程序運行期間不可改變摊聋。
- 數(shù)組的索引是從0開始的,一直到n-1(這個數(shù)組的長度為n);
- 數(shù)組一旦在內存中創(chuàng)建(不僅創(chuàng)建了儲存數(shù)組地址的變量栈暇,而且還要向系統(tǒng)要到固定長度的空間地址)了麻裁,長度就無法改變了!
數(shù)組的初始化
- 一、動態(tài)初始化(指定長度):
基本格式:數(shù)據(jù)類型[] 數(shù)組名稱 = new 數(shù)據(jù)類型[數(shù)組長度];
class Test {
public static void main(String[] args){
/**一步到位@*@*@*@ 推薦寫法 @*@*@*@*/
int[] array1 = new int[10];
/**分開寫*/
int[] array2;
array2 = new int[10];
/**錯誤的寫法
int[] array3;
array3 = {1, 2, 3, 4};
*/
}
}
注意:使用動態(tài)數(shù)組初始化數(shù)組的時候悲立,其中的元素會有一個默認值鹿寨,
初始化數(shù)據(jù)類型 | 整型:byte、short薪夕、int脚草、long | 浮點數(shù):double、float | 字符:char | boolean:true原献、false | 引用類型(對象) |
---|---|---|---|---|---|
默認值 | 0 | 0.0 | '\u0000' | false | null |
- 二馏慨、靜態(tài)初始化(指定內容):
基本格式:數(shù)據(jù)類型[] 數(shù)組名稱 = new 數(shù)據(jù)類型[] {item1, item2, ...};
提示:雖然靜態(tài)初始化沒有直接告訴長度,但是根據(jù)大括號里面的元素具體內容推算出數(shù)組的長度姑隅,這個是JVM底層的優(yōu)化写隶。
class Test {
public static void main(String[] args){
/**一步到位*/
int[] array1 = new int[]{1, 2, 3, 4, 5};
/**一步到位的簡寫形式@*@*@*@ 推薦寫法 @*@*@*@**/
int[] array2 = {1, 2, 4, 5, 6};
/**分開寫*/
int[] array3;
array3 = new int[]{1, 2, 3, 4, 5};
/**錯誤的寫法如下:
int[] array4;
array4 = {1, 2, 4, 5, 6};
*/
}
}
注意:直接打印數(shù)組的名稱,得到的結果是數(shù)組類型與內存地址哈希值的拼接(其實在源碼中讲仰,這個功能是在toString()這個方法中定義的慕趴,打印一個對象名,實際就是調用的這個方法鄙陡,可以對這個方法進行多態(tài)操作冕房,實現(xiàn)自己想要的效果)
二、以一維數(shù)組為例深入理解數(shù)組的引用(地址)
Java的內存劃分
Java的內存劃分主要分為5趁矾,個部分--> 棧(Stack)耙册、堆(Heap)、方法區(qū)(Method Area)毫捣、本地方法查找棧(Native Method Stack)详拙、寄存器(pc Register);一個class文件執(zhí)行的大致過程是 (提醒:這只是邏輯上的執(zhí)行,這層邏輯封裝了底層操作系統(tǒng)的具體調用以及具體的物理電路邏輯):JVM將.class字節(jié)碼文件加載方法區(qū)(就是一堆字符串)蔓同,然后解析饶辙,將方法壓入棧中 (這個方法區(qū)有其他的數(shù)據(jù)結構保存當前變量以及變量值,我猜是HashMap這種數(shù)據(jù)結構,如果錯誤請指出)在執(zhí)行中如果由遇到方法2牌柄,則將方法2壓入的棧中畸悬,直到這個方法執(zhí)行完了侧甫,然后又把之前的方法出棧繼續(xù)執(zhí)行珊佣。如果遇到new操作,則在另一個叫做內存區(qū)(堆這種數(shù)據(jù)結構)中創(chuàng)建并入堆一個對象披粟,并將地址賦值給相關的變量咒锻。
1. 一個數(shù)組從創(chuàng)建到操作經歷了哪些事?
2. 兩個同的數(shù)組
3. 兩個變量指向同一個數(shù)組
必須深入理解數(shù)組的引用守屉,變量中儲存的是數(shù)組對應的內存地址惑艇,如果對數(shù)組變量進行賦值操作,比如有個數(shù)組
int[] a = new int[3]; a = new int[]{1,2,3,4}
,對于這種情況,變量a指向一個新的長度為4的數(shù)組滨巴!
操作數(shù)組的一些注意事項:
數(shù)組的索引編號從0開始思灌,一直到“數(shù)組的長度-1”為止。如果訪問索引編號并不存在,拋出越界異常ArrayIndexOutOfBoundsException
所有的引用類型變量恭取,都可以賦值為一個null值泰偿。但是代表其中什么都沒有。數(shù)組必須進行new初始化才能使用其中的元素蜈垮。如果只是賦值了一個null耗跛,沒有進行new創(chuàng)建,那么將會發(fā)生:空指針異常 NullPointerException
如何獲取數(shù)組的長度攒发,格式:數(shù)組名稱.length
數(shù)組可以作為方法的參數(shù)调塌。當調用方法的時候,向方法的小括號進行傳參惠猿,傳遞進去的其實是數(shù)組的地址值羔砾。
一個方法可以有0、1偶妖、多個參數(shù)蜒茄;但是只能有0或者1個返回值,不能有多個返回值餐屎。如果希望一個方法當中產生了多個結果數(shù)據(jù)進行返回檀葛,怎么辦?解決方案:使用一個數(shù)組作為返回值類型即可腹缩。任何數(shù)據(jù)類型都能作為方法的參數(shù)類型屿聋,或者返回值類型。數(shù)組作為方法的參數(shù)藏鹊,傳遞進去的其實是數(shù)組的地址值润讥。數(shù)組作為方法的返回值,返回的其實也是數(shù)組的地址值盘寡。
三楚殿、二維數(shù)組
二維數(shù)組,顧名思義竿痰,就是一個數(shù)組中的元素也是一個數(shù)組脆粥,二維數(shù)組的第一層索引一定是一個對應數(shù)據(jù)類型的引用(一維的數(shù)組的引用),第二個索引可能是個引用也可能是個基本數(shù)據(jù)類型
二維數(shù)組的定義方式與使用方法
public class Test {
public static void main(String[] args) {
/**一影涉、動態(tài)初始化(指定長度)*/
int[][] array1 = new int[2][2];// @*@*@*@*@ 推薦方式1 @*@*@*@*@
int[][] array2 = new int[][]{{1,2,3}, {2,3,4}};
int[][] array3 = {{1,2,3},{5,6,7}};// @*@*@*@*@ 推薦方式2 @*@*@*@*@
int[][] array4;
array4= new int[][]{{1,4,5},{4,5,6}};
/**二变隔、靜態(tài)初始化(不指定長度),第一層索引必須制定*/
int[][] array5 = new int[5][];
int[][] array6;
array6 = new int[5][];
}
}
我利用二維數(shù)組舉了一個實際問題的栗子蟹倾,有點難度哦匣缘!
黑馬中學高三二班進行了一個期中考試猖闪,有一個5人小分隊,他們的成績如下score,對應的課程為subjects肌厨;對應的名字為studentsName培慌;請計算出并輸出①這5個同學的各自的最高分?②每一位同學的平均成績柑爸?③每一科的最高分检柬?④每一科的平均分?
public class Test {
public static void main(String[] args) {
double[][] score = {
{110, 120, 110, 80, 69, 59},
{97, 130, 120, 80, 65, 60},
{107, 145, 119, 80, 64, 55},
{99, 150, 130, 80, 66, 52},
{112, 150, 99, 80, 68, 56}
};
String[] subjects = {"語文", "數(shù)學", "英語", "物理", "生物", "化學"};
String[] studentsName = {"李逍遙", "梅長蘇", "景天", "蒙毅", "寧采臣"};
statisticsScore(score, subjects, studentsName);
}
public static void statisticsScore(double[][] score, String[] subjects, String[] studentsName) {
// 記錄每一位同學的最高分
double[] highScoreStudent = new double[score.length];
// 記錄每一位同學的平均成績
double[] averageScoreStudent = new double[score.length];
// 記錄每一科的最高分
double[] hightScoreSubject = new double[score[0].length];
// 記錄每一科的平均分
double[] averageScoreSubject = new double[score[0].length];
// 計算每一位學生的信息----->橫向遍歷
for(int i = 0; i < score.length; i ++) {
double sumScoreStu = 0; // 累計當前同學的總分
for(int j = 0; j < score[i].length; j ++) {
// 記錄當前同學的最高分
if(score[i][j] > highScoreStudent[i])
highScoreStudent[i] = score[i][j];
// 累計總分
sumScoreStu += score[i][j];
}
// 計算并記錄當前同學的平均分
averageScoreStudent[i] = sumScoreStu / score[i].length;
}
// 計算每一門學科的信息----->縱向遍歷
for(int i = 0; i < score[0].length; i ++) {
double sumScoreSub = 0; // 累計當前學科的總分
for(int j = 0; j < score.length; j ++) {
if(score[j][i] > hightScoreSubject[i])
hightScoreSubject[i] = score[j][i];
sumScoreSub += score[j][i];
}
averageScoreSubject[i] = sumScoreSub / score.length;
}
printMsg(subjects, studentsName, highScoreStudent, averageScoreStudent,
hightScoreSubject, averageScoreSubject);
}
public static void printMsg(String[] subjects, // 學科名稱
String[] studentsName, // 同學姓名
double[] highScoreStudent, // 同學最高成績
double[] averageScoreStudent, // 同學平均成績
double[] hightScoreSubject, // 學科最高分
double[] averageScoreSubject) { // 學科平均分
System.out.println("*************************** 每一位同學的信息 ***************************");
System.out.println("---------------------------------------------------------------------");
System.out.print("| 學生姓名 | ");
for(int i = 0; i < studentsName.length; i ++) {
System.out.printf("%5s\t | ", studentsName[i]);
}
System.out.println();
System.out.println("---------------------------------------------------------------------");
System.out.print("| 最高成績 | ");
for(int i = 0; i < highScoreStudent.length; i ++) {
System.out.printf("%5.2f\t | ", highScoreStudent[i]);
}
System.out.println();
System.out.println("---------------------------------------------------------------------");
System.out.print("| 平均成績 | ");
for(int i = 0; i < averageScoreStudent.length; i ++) {
System.out.printf("%5.2f\t | ", averageScoreStudent[i]);
}
System.out.println();
System.out.println("---------------------------------------------------------------------");
System.out.println();
System.out.println("*************************** 每一個學科的信息 ***************************");
System.out.println("--------------------------------------------------------------------------------");
System.out.print("| 學科名稱 | ");
for(int i = 0; i < subjects.length; i ++) {
System.out.printf("%5s\t | ", subjects[i]);
}
System.out.println();
System.out.println("--------------------------------------------------------------------------------");
System.out.print("| 最高成績 | ");
for(int i = 0; i < hightScoreSubject.length; i ++) {
System.out.printf("%5.2f\t | ", hightScoreSubject[i]);
}
System.out.println();
System.out.println("--------------------------------------------------------------------------------");
System.out.print("| 平均成績 | ");
for(int i = 0; i < averageScoreSubject.length; i ++) {
System.out.printf("%5.2f\t | ", averageScoreSubject[i]);
}
System.out.println();
System.out.println("--------------------------------------------------------------------------------");
}
}
輸出結果(非常像一個數(shù)據(jù)庫查詢的結果)
四竖配、多維數(shù)組
多維數(shù)組就是指數(shù)組的元素層層嵌套數(shù)組何址。在定義的時候,第一索引必須指定进胯。執(zhí)行索引之間不能不能指定索引用爪;多維數(shù)組除了最后一層可以儲存對象和基本數(shù)據(jù)類型,其他層次的必須儲存對應類型的引用(對應維度的數(shù)組引用)
舉一個栗子
public class Test {
public static void main(String[] args) {
/**多維數(shù)組,以一個四維數(shù)組為栗子*/
/**正確的寫法*/
int[][][][] arrays1 = new int[4][][][];
int[][][][] arrays2 = new int[4][3][][];
int[][][][] arrays3 = new int[4][3][2][];
int[][][][] arrays4 = new int[4][3][2][1];
arrays4[4][3] = new int[7][3]; // 儲存對應類型的引用
/**錯誤的寫法
int[][][][] arrays5 = new int[][][][];
int[][][][] arrays6 = new int[][3][][];
int[][][][] arrays7 = new int[4][][2][];
*/
}
}