1. 數組的概念
-
數組就是一組相關變量的集合,比如用數組可以實現100個變量的定義。
-
數組的動態初始化定義:
- 聲明並開闢數組:數據類型 數組名稱[ ] = new 數據類型[長度]
- 分步定義:
- 聲明數組:數據類型 數組名稱[ ] = null;
- 開闢數組:數組名稱 = new 數據類型[長度]
- 可以看出來聲明數組的時候才使用[ ]
-
數組的靜態初始化定義:
-
一、簡化格式:數據類型 數組名[ ] = {值,值,值….}
-
二、完整格式:數據類型 數組名[ ] = new 數據類型[ ] {值,值,…}
-
public class Hello{ public static void main(String args[]){ int arr[] = new int[]{1,2,3,4,5}; for(int x=0; x<arr.length; x++ ){ System.out.println(arr[x]); } } }
-
-
數組的訪問:數組名稱[下標 | 索引]、所有的下標都是從0開始的
-
獲取數組長度:數組名稱.length
-
循環獲取數組所有的元素
-
public class Hello{ public static void main(String args[]){ int arr[] = new int[3]; arr[1] = 123; for(int x=0; x<arr.length; x++ ){ System.out.println(arr[x]); } } }
-
由於數組屬於引用數據類型,所以他的最麻煩的地方在於內存的分配。
-
對象中的堆內存保存的是屬性,而數組中的堆內存保存的是一組信息
2. 數組的引用傳遞
引用傳遞本質上就是堆內存被多個棧內存所指向
public class Hello{
public static void main(String args[]){
int arr[] = new int[3];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
int temp[] = arr; //arr的地址傳遞給temp數組、就完成了數組的引用傳遞
temp[0] = 99;
for(int x=0; x<arr.length; x++ ){
System.out.println(arr[x]);
}
}
}
//輸出是
99
20
30
3.注意
- 工作中一般是通過數據傳遞的方法使用數組,不會主動開闢空間再去使用。
- 數組的最大缺點是長度不能改變。
4. 二維數組
-
二維數組就是有兩個[ ]
-
二維數組的定義
- 動態定義:數組類型 數組名[ ][ ] = new 數組類型[ 行長度 ] [ 列長度 ]
- 靜態定義:數組類型 數組名[ ][ ] = new 數組類型[ ][ ] {{值,值,值},{值,值,值}}
-
注意:實際開發中很少出現直接編寫的二維數組。
5.數組與方法的參數傳遞
之前學的方法裏面傳入的參數基本上都是基本數據類型、當傳入的是數組的時候,一定要注意觀察內存分配圖。如下面的
5.1 數組傳遞的範例:
public class Hello{
public static void main(String[] args){
// 定義數組
int arr[] = new int[] {1,2,3,4,5};
// 將上面的數組傳入到調用的函數中
change(arr);
// 輸出數組的元素
for(int i=0; i<arr.length; i++){
System.out.println(arr[i]);
}
}
// 此方法定義在主類中,由主方法直接調用
public static void change(int[] temp){
for(int i=0; i<temp.length; i++){
temp[i] *= 2;
}
}
}
//輸出是
2
4
6
8
10
上面的代碼與下面的代碼實現的結果是一樣的
public class Hello{
public static void main(String[] args){
// 定義數組
int arr[] = new int[] {1,2,3,4,5};
// 定義另一個數組,將arr引用傳遞給它
int temp[] = arr;
// 對temp的元素*=2
for(int i=0; i<temp.length; i++){
temp[i] *= 2;
}
// 輸出數組的元素
for(int i=0; i<arr.length; i++){
System.out.println(arr[i]);
}
}
}
也就是說、將一個數組作爲參數傳入到函數中,實際上是傳入的該數組的棧內存中存儲的堆內存的地址,方法對數組做的修改一定會被保留下來。內存中的改變如下:
5.2 一個數組的冒泡排序算法
升序排序的基本算法,按順序兩兩比較,後者小於前者則交換位置
原始數據:2、1、9、0、5、3、7、6、8;
第一次排序:1、2、0、5、3、7、6、8、9
第二次排序:1、0、2、3、5、6、7、8、9
第三次排序:0、1、2、3、5、6、7、8、9
按照此種方法進行排序次數(大的次數)不會操作數組的總長度,所以只要排序總次數
public class Hello{
public static void main(String[] args){
int arr[] = new int[] {2,1,9,0,5,3,7,6,8};
printOut(arr,"排序前的輸出");
order(arr);
printOut(arr,"排序後的輸出");
}
// 此函數用於排序
public static void order(int temp[]){
for(int j=0; j<temp.length; j++){
for(int i=0; i<temp.length-1; i++){
int container = 0;
if(temp[i] > temp[i+1]){
container = temp[i];
temp[i] = temp[i+1];
temp[i+1] = container;
}
}
}
}
// 此函數用於輸出
public static void printOut(int temp[],String printType){
System.out.println(printType);
for(int i=0; i<temp.length; i++){
System.out.println(temp[i]);
}
}
}
// 輸出結果
排序前的輸出
2
1
9
0
5
3
7
6
8
排序後的輸出
0
1
2
3
5
6
7
8
9
5.3 實現數組的轉置(首位交換)
原始數組:1,2,3,4,5,6,7,8,9
轉置後的數組:9,8,7,6,5,4,3,2,1
思路一:定義一個新的數組,將源數組按倒序插入到新的數組裏面,但是這種方式會產生垃圾,不推薦使用
public class Hello{
public static void main(String[] args){
int arr[] = new int[] {1,2,3,4,5,6,7,8,9};
printOut(arr,"轉之前的輸出");
transpose(arr);
}
// 此函數用於轉置
public static void transpose(int temp[]){
// 動態定義一個新的數組
int newArr[] = new int[temp.length];
int i,j;
for(i=temp.length-1,j=0; i>-1 && j<temp.length; i--,j++){
newArr[j] = temp[i];
}
printOut(newArr,"轉置後的輸出");
}
// 此函數用於輸出
public static void printOut(int temp[], String printType){
System.out.println(printType);
for(int i=0; i<temp.length; i++){
System.out.print(temp[i]+" ");
}
System.out.println('\n');
}
}
// 輸出結果
轉之前的輸出
1 2 3 4 5 6 7 8 9
轉置後的輸出
9 8 7 6 5 4 3 2 1
思路二:直接在源數組的基礎上進行轉置
public class Hello{
public static void main(String[] args){
int arr[] = new int[] {1,2,3,4,5,6,7,8,9};
printOut(arr,"轉之前的輸出");
transpose(arr);
printOut(arr,"轉之後的輸出");
}
// 此函數用於轉置
public static void transpose(int temp[]){
for(int i=0; i<= (temp.length-1)/2; i++){
int container = 0;
container = temp[i];
temp[i] = temp[temp.length-1-i];
temp[temp.length-1-i] = container;
}
}
// 此函數用於輸出
public static void printOut(int temp[], String printType){
System.out.println(printType);
for(int i=0; i<temp.length; i++){
System.out.print(temp[i]+" ");
}
System.out.println('\n');
}
}
5.4 方法返回數組
重點關注方法的返回值就可以了
public class Hello{
public static void main(String[] args){
System.out.println(init().length);
}
public static int[] init(){
// 返回一個匿名數組
return new int[] {1,2,3};
}
}
6.兩個與數組相關的系統內置方法
6.1 數組的拷貝
- 概念:將數組中的部分內容拷貝到另外一個數組之中
- 語法:System.arraycopy(原數組名稱,原數組拷貝開始索引,目標數值名稱,目標數組拷貝開始索引,拷貝長度)
舉例:實現數組拷貝
- 數組A:1,2,3,4,5,6,7,8
- 數組B:11,22,33,44,55,66,77,88
- 要求拷貝後的數組B:11,22,5,6,7,66,77,88
public class Hello{
public static void main(String[] args){
int arrA[] = new int[] {1,2,3,4,5,6,7,8};
int arrB[] = new int[] {11,22,33,44,55,66,77,88};
System.arraycopy(arrA,4,arrB,2,3);
for(int i=0; i<arrB.length; i++){
System.out.println(arrB[i]);
}
}
}
6.2 數組的排序
- 語法:java.util.Arrays.sort(數組名);
7.對象數組(重點)
-
說白了就是同時實例化多個類,將其放到一個數組當中,將多個對象交給數組統一管理
-
概念:引用類型裏面嵌套了其他的引用類型,之前定義的數組都是用的基本數據類型的數組,但是所有的引用數據類型也同樣可以定義數組,這樣的數組稱爲對象數組。二維數組其實也是對象數組
-
對象數組一般就是一維
-
動態初始化:
- 聲明並開闢對象數組:類名稱 對象數組名稱[] = new 類名稱[長度];
- 分步完成:
- 聲明對象數組:類名稱 對象數組名稱[] = null;
- 開闢對象數組:對象數組名稱 = new 類名稱[長度];
-
靜態初始化:類名稱 對象數組名稱[] = new 類名稱[] {實例化對象,實例化對象}
class Book{
private String title;
private int price;
// 構造方法
public Book(String t,int p){
title = t;
price = p;
}
// 輸出信息
public String getInfo(){
return "圖書價格"+price+",圖書標題"+title;
}
}
public class Hello{
public static void main(String[] args){
// 動態初始化對象數組
Book bo[] = new Book[3];
// 分別實例化對象
bo[0] = new Book("java",23);
bo[1] = new Book("Python",34);
bo[2] = new Book("cv",45);
// 輸出所有對象信息
for(int i=0;i<bo.length;i++){
System.out.println(bo[i].getInfo());
}
}
}
8.總結
-
數組用的很少,但是一定會用,而且數組的相關邏輯比較麻煩
- 把數組的轉置和排序弄明白
-
一切以一位數組爲主,要明白數組的定義語法和內存的關係(對象一致)
-
對象數組的定義語法,對象數組 = 多個對象
-
數組的天生最大短板:長度固定,所以這就限制了數組在開發中的出現
-
數組的排序:java.util.Arrays.sorts()