Java基礎語法之陣列
阿新 • • 發佈:2018-12-19
目錄
1. 陣列的概念及特點
陣列:
陣列是儲存同一種資料型別的多個元素的集合,也可以看成是一個容器。
特點:
- 既可以儲存基本資料型別又可以儲存引用資料型別
- 每一個元素都有編號,從0開始,最大編號是長度-1。編號的專業叫法:索引
2. 陣列的定義格式
有兩種,效果一樣,念法不同,常用格式1
- 資料型別[] 陣列名;
- 資料型別 陣列名[];
int [] a;//定義一個int型別的陣列a變數,此時的數組裡沒有元素,需要對其進行初始化操作 int a [];//定義一個int型別的a陣列變數
3. 陣列的初始化
Java中的陣列必須先初始化,然後才能使用
3.1 概念
所謂初始化:
就是為陣列中的陣列元素分配記憶體空間,併為每個陣列元素賦值。
3.2 初始化方式
3.2.1 動態初始化
動態初始化:
初始化時只指定陣列長度,由系統為陣列分配初始值。
陣列長度其實就是陣列中元素的個數
動態初始化格式:
資料型別[] 陣列名 = new 資料型別[陣列長度]; //舉例: int[] arr = new int[3]; //解釋:定義了一個int型別的陣列array,這個陣列中可以存放3個int型別的值 /* 左邊: int:表示陣列中的元素的資料型別為int; []:說明這是一個數組; arr:這是這個陣列的名稱; 右邊: new:為陣列分配記憶體空間; int:表示陣列中的元素的資料型別為int; []:說明這是一個數組; 3:陣列長度,即陣列中元素的個數 */
注意:
- 直接訪問陣列名得到的是地址值
- 訪問數組裡的元素格式:陣列名[索引]
3.2.2 靜態初始化
靜態初始化:
初始化時指定每個陣列元素的初始值,由系統決定陣列長度。
靜態初始化格式:
資料型別[] 陣列名 = new 資料型別[]{元素1,元素2,……};
或者:
資料型別[] 陣列名 = {元素1,元素2,……};
//舉例:
int[] arr = new int[]{1,2,3};
//簡化寫法:
int[] arr = {1,2,3};
//解釋:定義了一個int型別的陣列,這個陣列中存放3個int型別的值,並且值分別是1,2,3
4.Java中的記憶體分配
4.1 概述
Java 程式在執行時,需要在記憶體中分配空間。
為了提高運算效率,就對空間進行了不同區域的劃分,因為每一片區域都有特定的處理資料方式和記憶體管理方式。
4.2 5個記憶體空間
棧(儲存區域性變數)
- 區域性變數:方法定義中或者方法宣告上的所有變數
特點:棧記憶體的資料用完(脫離作用域)就釋放
堆(儲存new出來的東西)
特點:
- 每一個new出來的東西都有一個地址值;
- 每個變數都有預設值;(byte,short int long預設值為0;float,double預設值為 0.0;char預設值為'\u0000';boolean預設值為false;引用型別預設值為null)
- 資料使用完畢後,不會立即釋放,在垃圾回收器空閒的時候回收
方法區(面向物件部分講解)
本地方法區(和系統有關)
暫存器(給CPU用)
4.3 陣列記憶體圖解(理解)
5.陣列的常用操作
5.1 陣列遍歷
陣列遍歷:即依次輸出陣列中每一個的元素
陣列提供了一個屬性:length來專門獲取陣列長度
//獲取陣列長度的格式
陣列名.length
案例1:一個數組的遍歷
//一個數組遍歷
class ArrayTest1 {
public static void main(String[] args) {
//定義一個數組
int[] arr = {11,22,33,44,55,66};
//用格式:陣列名.length來獲取陣列長度
for(int x = 0;x<arr.length;x++) {
System.out.println(arr[x]);
}
}
}
案例2:對多個數組遍歷(使用方法)
//通過呼叫遍歷方法對多個數組進行遍歷
//方法:兩個明確——返回值型別void;引數列表int [] arr
class ArrayTest2 {
public static void main(String[] args) {
//定義陣列
int[] arr1 = {1,2,3,4,5};
int[] arr2 = {11,22,33,44};
//直接呼叫遍歷陣列方法
printArray(arr1);
System.out.println("----------");
printArray(arr2);
}
//遍歷陣列的方法
public static void printArray(int[] arr) {
for(int x = 0;x<arr.length;x++) {
System.out.println(arr[x]);
}
}
}
5.2 陣列獲取最值
案例3:獲取陣列中的最大值
思路:
- 假設陣列中的第一個元素為最大值——將arr[0]暫時賦值給變數max;
- 將max與第二個元素進行比較——if語句判斷;
- 如果max較小,就將第二個元素的值賦給變數max,並繼續比較max與下一個元素的大小;
- 如果max較大,不進行賦值操作,直接與下一個元素比較大小——3,4步無論如何都要獲取剩下的元素的值(陣列遍歷)
//獲取陣列元素中的最大值
class ArrayTest3 {
public static void main(String[] args) {
//定義一個數組
int [] arr = {34,98,12,4,69,127,88,56};
//假設陣列中的第一個元素就是最大值
int max = arr[0];
//遍歷剩下的元素與進行比較
for(int x = 1;x<arr.length;x++) {
//遍歷的元素較大時,將其賦值給max
if(arr[x] > max) {
max = arr[x];
}
}
System.out.println("max:"+max);
}
}
用方法改進:
兩個明確:
- 返回值型別——int;返回的int型別的最大值
- 引數列表——int [] arr
//用方法獲取陣列元素中的最大值
class ArrayTest4 {
public static void main(String[] args) {
//定義陣列
int [] arr = {34,98,12,4,69,127,88,56};
//呼叫getMax方法並賦值給變數max,呼叫方法時不用再寫資料型別
int max = getMax(arr);
System.out.println("max:"+max);
}
//寫獲取陣列元素最大值的方法
public static int getMax(int[] arr) {
//定義一個變數max,將陣列第一個元素賦值給它(因為在不同方法裡定義的所以沒有影響)
int max = arr[0];
//遍歷剩餘元素進行比較賦值
for(int x = 1;x<arr.length;x++) {
if(arr[x] > max) {
max = arr[x];
}
}
//迴圈結束後返回陣列中的最大值到呼叫方法處
return max;
}
}
5.3 陣列元素逆序
案例4:把元素順序對調
思路:
- 將0索引的資料和arr.length-1對換;
- 將1索引的資料與arr.length-2對換;
- ……
- 對調次數:arr.length/2(偶數個元素時剛好配對,奇數個元素時由於計算時商取得整數且中間多出來的元素位置不變,無影響)
//陣列元素逆序
class ArrayTest5 {
public static void main(String[] args) {
//定義一個數組
int[] arr = {1,2,3,4};
System.out.println("逆序前:");
//呼叫遍歷方法
printArray(arr);
System.out.println("逆序後:");
//呼叫逆序方法
reverse(arr);
//呼叫陣列遍歷方法
printArray(arr);
}
//寫逆序方法
public static void reverse(int[] arr) {
for(int x = 0;x < arr.length/2;x++) {
int temp = arr[x];
arr[x] = arr[arr.length-1-x];
arr[arr.length-1-x] = temp;
}
}
//遍歷陣列
public static void printArray(int[] arr) {
System.out.print("[");
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) {
System.out.println(arr[x]+"]");
}else {
System.out.print(arr[x]+", ");
}
}
}
}
5.4 陣列查表法
案例5:根據鍵盤錄入索引,查詢對應星期
//根據索引查詢星期
//導包
import java.util.Scanner;
class ArrayTest6 {
public static void main(String[] args) {
//定義一個字串陣列
String[] arr = {"星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
//建立鍵盤錄入物件
Scanner sc = new Scanner(System.in);
System.out.println("請輸入索引號(0~6):");
int number = sc.nextInt();
System.out.println("你要查詢的日期是:"+arr[number]);
}
}
5.5 陣列元素查詢
案例6:查詢指定元素第一次在陣列中出現的索引
思路:
- 定義一個數組並靜態初始化;
- 鍵盤錄入要查詢的資料;
- 遍歷陣列,依次獲取陣列中的每一個元素與該資料進行比較;
- 如果想等,就返回當前索引
//導包
import java.util.Scanner;
class ArrayTest7 {
public static void main(String[] args) {
//定義一個數組
int[] arr = {12,76,90,56,349,24,35};
//建立鍵盤錄入物件
Scanner sc = new Scanner(System.in);
System.out.println("請輸入一個數據:");
int value = sc.nextInt();
//呼叫方法
int index = getIndex(arr,value);
System.out.println(value+"在陣列中的第一次索引是:"+index);
}
//寫方法獲取索引:返回值型別:int;引數列表:int[] arr,int value
public static int getIndex(int[] arr,int value) {
//遍歷陣列
for(int i=0;i<arr.length;i++) {
//元素與資料進行比較,相等就返回索引,不相等就沒有資料返回,會報錯,要在後面返回負數
if(arr[i] == value) {
//要考慮不相等時候的返回值
return i;
}
}return -1;//如果找不到資料,一般返回一個負數
}
}
5.6 陣列排序和二分查詢(後續講)
6.二維陣列
6.1 二維陣列的定義
二維陣列其實就是一個元素為一維陣列的陣列
6.2 二維陣列的定義格式
格式1(列固定的二維陣列動態初始化):
資料型別[][] 變數名 = new 資料型別[m][n];
也可以寫成另外兩種格式但是不推薦:
A:資料型別 陣列名[][] = new 資料型別[m][n];
B:資料型別[] 陣列名[] = new 資料型別[m][n];
int x,y; 等價於 int x;int y;
int[] x,y[]; 等價於 int[] x;int[] y[];//x為一位陣列,y為二維陣列
m表示這個二維陣列有多少個一維陣列
n表示每一個一維陣列的元素個數
//舉例:
int[][] arr = new int[3][2];
//定義了一個二維陣列arr
//這個二維陣列有3個一維陣列,名稱是arr[0],arr[1],arr[2]
//每個一維陣列有2個元素,可以通過arr[m][n]來獲取
//表示獲取第m+1個一維陣列的第n+1個元素
案例7:
//二維陣列(理解記憶體圖解)
class Array2Demo {
public static void main(String[] args) {
//定義一個二維陣列
int[][] arr = new int[3][2];
//在堆裡開闢一個二維陣列的記憶體空間並分配為3塊生成一個地址值並賦給棧裡對應的區域
System.out.println(arr);//輸出結果[[[email protected]
/*
堆裡的二維陣列分配的3個空間用來儲存一維陣列(引用型別)初始值均為null,
等一維陣列記憶體空間分配完畢後生成地址值替代null
*/
System.out.println(arr[0]);//輸出結果[[email protected]
System.out.println(arr[1]);//輸出結果[[email protected]
System.out.println(arr[2]);//輸出結果[[email protected]
//開闢並分配一維陣列的記憶體空間
System.out.println(arr[0][0]);//輸出結果0
System.out.println(arr[0][1]);//輸出結果0
}
}
格式2(列變化的二維陣列動態初始化):
資料型別[][] 變數名 = new 資料型別[m][];
m表示這個二維陣列有多少個一維陣列
這一次沒有直接給出一維陣列的元素個數,可以動態的給出。
//舉例:
int[][] arr = new int[3][];
arr[0] = new int[2];
arr[1] = new int[3]
arr[2] = new int[1];
//二維陣列
class Array2Demo {
public static void main(String[] args) {
//定義一個二維陣列
int[][] arr = new int[3][];
//輸出二維陣列
System.out.println(arr);//輸出地址值
//此時沒有為一位陣列分配空間所以地址值為預設值
System.out.println(arr[0]);//輸出null
System.out.println(arr[1]);//輸出null
System.out.println(arr[2]);//輸出null
//動態的為每一個一維陣列分配空間
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
//輸出二維陣列中的一維陣列
System.out.println(arr[0]);//輸出地址值
System.out.println(arr[1]);//輸出地址值
System.out.println(arr[2]);//輸出地址值
}
}
格式3(靜態初始化):
資料型別[][] 變數名 = new 資料型別[][]{{元素…},{元素…},{元素…}};
簡化版格式:
資料型別[][] 變數名 = {{元素…},{元素…},{元素…}};
//舉例:
int[][] arr = {{1,2,3},{4,6},{6}};
6.3 二維陣列的練習
6.3.1 二維陣列遍歷
//二維陣列遍歷
class Array2Test {
public static void main(String[] args) {
//定義一個二維陣列
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
//遍歷二維陣列中的一維陣列
for(int x = 0;x < arr.length;x++) {
//遍歷一維陣列中的元素
for(int y = 0;y < arr[x].length;y++){
System.out.println(arr[x][y]);
}
System.out.println("-------");
}
}
}
方法改進:
//二維陣列遍歷的方法改進
class Array2Test1 {
public static void main(String[] args) {
//定義一個二維陣列
int[][] arr = {{1,2,3},{4,5,6},{7,8,9}};
int[][] arr2 = {{1,2,3},{4,5},{6}};
//呼叫方法
printArray2(arr);
printArray2(arr2);
}
//寫方法:返回值型別——void;引數列表——int[][] arr;
public static void printArray2(int[][] arr) {
for(int x =0;x<arr.length;x++) {
for(int y = 0;y<arr[x].length;y++) {
System.out.println(arr[x][y]);
}
System.out.println("-------");
}
}
}
6.3.2 二維陣列求和
思路:
首先獲取每一個元素(遍歷),然後元素累加
//二維陣列元素求和
class Array2Test2 {
public static void main(String[] args) {
//定義一個二維陣列
int[][] arr = {{22,66,44},{77,33,88},{25,45,65},{11,66,99}};
//定義和變數
int sum = 0;
//遍歷
for(int x = 0;x<arr.length;x++) {
for(int y = 0;y<arr[x].length;y++) {
sum += arr[x][y];
}
}
System.out.println("一年的銷售額為:"+sum);
}
}
6.3.3 二維陣列求楊輝三角
要求行數鍵盤錄入
分析:
- 行數與列數相等,由鍵盤錄入;
- 每一行的第一列和最後一列都是1;
- 從第三行開始,每個資料是它上一行的前一列和本列之和(除了第一列和最後一列)
//二維陣列列印楊輝三角
//導包
import java.util.Scanner;
class Array2Test3 {
public static void main(String[] args) {
//建立鍵盤錄入物件
Scanner sc = new Scanner(System.in);
System.out.println("請輸入行數:");
int n = sc.nextInt();
//定義一個二維陣列
int[][] arr = new int[n][n];
//給任一行的第一列和最後一列賦值1
for(int x = 0;x < arr.length;x++) {
arr[x][0] = 1;
arr[x][x] = 1;
}
//從第三行開始,每一行第二列到第n-1列的值=上一行前一列的數+上一行該列的數
for(int x = 2;x<arr.length;x++){
for(int y = 1;y <= x-1;y++) {
arr[x][y] = arr[x-1][y-1] + arr[x-1][y];
}
}
//輸出形式
for(int x=0; x<arr.length; x++) {
for(int y=0; y<=x; y++) {
System.out.print(arr[x][y]+"\t");
}
System.out.println();
}
}
}
思考題
Java中的引數傳遞問題 Java中只有值傳遞。 基本型別:形式引數的改變不影響實際引數 引用型別:形式引數的改變直接影響實際引數
//Java中的引數傳遞問題,在Java中只有值傳遞
class ArgsDemo {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("a:"+a+",b:"+b); //a:10,b:20
//方法中形參的改變不影響a,b的實際引數
change(a,b);
System.out.println("a:"+a+",b:"+b); //a:10,b:20
int[] arr = {1,2,3,4,5};
//傳遞的是地址值,地址值指向堆記憶體中儲存的元素
//在引用資料型別中,形參的改變直接影響實際引數
change(arr);
System.out.println(arr[1]); //4
}
public static void change(int a,int b) { //a=10,b=20
System.out.println("a:"+a+",b:"+b); //a:10,b:20
a = b; //a=20
b = a + b; //b=40
System.out.println("a:"+a+",b:"+b); //a:20,b:40
}
public static void change(int[] arr) { //arr={1,2,3,4,5};
for(int x=0; x<arr.length; x++) {
if(arr[x]%2==0) {
arr[x]*=2;
}
}
//arr={1,4,3,8,5};
}
}