數組
存儲一組同一個類型數據的容器---數組
數組對每一個存入的數字都會自動編號,編號是從0開始的---下標
定義格式:
數據類型[] 數組名 = new 數據類型[表示數組能存放的元素個數];---適用於一些知道元素個數而不知道具體元素的場景
int[] arr = new int[5]; --- 表示定義了一個能存儲5個int類型的數據的數組
Java中對數組中的元素進行了自動的編號。---編號是從0開始的。---下標
注意:數組一旦定義好,大小不可變
arr[1] = 5; int i = arr[1];
int i = 5;
int i; //聲明 i = 5; //初始化---在程序中第一次給變量賦值
int[] arr;
arr = new int[5];---可以先聲明再初始化
arr[2] = 15; System.out.println(arr[2]);
數據類型[] 數組名 = new 數據類型[]{元素1, 元素2,……,元素n};---同時也就規定了數組的大小就是元素的個數
int[] arr = new int[]{3,5,1,2,5};arr[3] = 10;---在定義好之後,數組的初始元素已經一一賦值,數組的大小已經固定。可以先聲明再初始化嗎?---可以
數據類型[] 數組名 = {元素1, 元素2,……,元素n};
int[] arr = {2,6,4,7,9};//在創建的時候動態的獲取數組大小,然後才能分配內存空間int[] arr;
arr = {1,5,3,7,4};---不可以---現在不知道數組的大小
內存
Java將內存分爲了五塊:棧內存,堆內存,方法區,本地方法棧,寄存器
棧內存
變量是存儲在棧內存中的。
存儲變量,執行代碼塊的。變量存儲在棧內存中不會自動賦予初始值,變量使用完成之後立即移除出棧內存,釋放空間
堆內存
存儲的是對象。對象在堆內存中會自動的賦予一個默認值。
---初始值:byte/short/int---0, long---0L
float---0.0f, double---0.0, char---‘\u0000’, boolean---false, 所有的引用類型的默認值全部都是null
對象在使用完成之後,不會立即移除,而是在不定的某個時刻被回收。
----------------------------------------------------------------------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------
ArrayIndexOutOfBoundsException---數組下標越界異常---編譯沒有問題---說明明語法沒有問題---邏輯上或者事實上不符合--運行出錯
NullPointorException---空指針異常---編譯沒有問題---對於null而言,不能做任何操作
int i = 5; int j = i;
注意:對於基本類型而言,傳值傳的實際的數據;對於引用類型而言,傳值傳的是地址。
----------------------------------------------------------------------------
數組的應用
1. 獲取指定位置上的元素---數組名[下標]
2. 獲取數組的長度---數組名.length
3. 遍歷數組
A. 普通for循環
for(int i = 0; i < arr.lenth; i++){}
B. 增強for循環
for(int i : arr){ // 表示把數組中的元素依次取出賦值給i // 無法改變原來的元素了 System.out.println(i); }
C. String str = Arrays.toString(數組);
4. 獲取數組元素的最值。---獲取最大值---遍歷數組
5. 數組元素排序
冒泡排序:
for(int i = 1 ; i < arr.length ; i++){ //控制輪數 for(int j = 1; j <= arr.length - i; j++){ //控制每輪的次數,以及下標 if(arr[j - 1] > arr[j] ){ int temp = arr[j - 1]; arr[j - 1] = arr[j]; arr[j] = temp; } } }
選擇排序:
for(int i = 1; i < arr.length ; i++){ //控制輪數和起始下標 for(int j = i - 1; j < arr.length; j++){ //控制次數,後邊那一位的下標的變化 if(arr[i - 1] > arr[j]){ int temp = arr[i - 1]; arr[i - 1] = arr[j]; arr[j] = temp; } } }
快速排序、希爾排序、堆排序
import java.util.Arrays;
Arrays.sort(數組); //只能升序排列---從小到大
String s = Arrays.toString(arr);---將數組中的元素依次取出拼接成了一個字符串
6. 查找元素的位置
A. 遍歷
B. 折半查找---要求數組有序---時間複雜度:O(log2n)
無序數組---for循環
有序數組---折半查找
7. 反轉數組---頭尾交換
利用新的數組,也可以利用兩個變量來同時操作數組的兩端
注意:如果訪問的下標不存在,會出現ArrayIndexOutOfBoundsException---數組下標越界異常---編譯的時候沒有報錯---因爲語法無錯。---所以編譯檢查的是語法問題
8. 數組的擴容---數組的複製
System.arraycopy(要複製的數組,要複製的數組的起始位置,被複制到的數組,新數組中放置的起始位置,要複製的元素的個數);
System.arraycopy(arr,3,arr2,2,5);---從arr下標爲3的位置開始複製,複製5個元素到arr2中,從arr2的下標爲2的位置開始依次存放
數組 = Arrays.copyOf(要擴容的數組, 擴容之後的大小);---表面上看起來對數組的長度做了改變,實際上數組已經發生了變化,已經是一個新的數組---數組在擴容完成之後,堆內存的地址已經發生了改變
Arrays.copyOf(arr,len); int[] arr2 = new int[len]; if(len < arr.length){ System.arraycopy(arr,0,arr2,0,len); } else { System.arraycopy(arr,0,arr2,0,arr.length); }
T[] arr2; //數據類型在Java底層動態獲取的
arr2 = new T[長度]; //T---表示泛型
if(長度 >= 數組.length){
System.arraycopy(arr,0,arr2,0,arr.length);
} else {
Sysetem.arraycopy(arr,0,arr2,0,長度);
}
arr = arr2;
補充擴展:
1. int i = 1 / 0;---編譯沒有問題---運行---ArithmeticException---算術異常
在Java中小數允許除以0,結果是Infinity/NaN---Not a Number---NaN和任何值都不相等,即使是本身,也不相等。
2. 儘量減少使用小數作爲控制條件----因爲小數在計算機中不能夠精確存儲
3. strictfp---在函數執行過程中,小數是以80位二進制進行存儲的,但是函數完成之後,依然使用double類型存儲最終的結果---最終的結果依然是64位二進制小數
二維數組
二維數組的每一個元素就是一個一維數組---是一個存放數組的容器---數組的數組
定義格式
數據類型[][] 數組名 = new 數據類型[二維數組的大小/二維數組中包含的一位數組的個數][所包含的一維數組的大小];
int[][] arr = new int[3][5];---表示這是一個包含3個一維數組的二維數組,每個一維數組由5個整數組成
int[] arr2 = arr[0];----獲取的是一個一維數組
arr[0][3];---如果獲取具體的元素,需要兩個下標
數據類型[][] 數組名 = new 數據類型[二維數組的大小/包含的一維數組的個數][];
int[][] arr = new int[3][];---表示這個二維數組由3個整型的一維數組組成
arr[0][0] = 3; ---不可以---因爲所包含的一維數組沒有初始化
arr[3][0] = 8;---NullPointerException---空指針異常
數據類型[][] 數組名 = {{元素1},{元素1,元素2} ……};
int[][] arr = {{1},{1,3},{2,4,3}};
arr[0][1] = 5;--不可以
注意:針對null的任何操作都會出現空指針異常
面試題總結:對於數組int[] x,y[]均已初始化,下列選項正確的是:
對於數組int[] x, y[]均已初始化,下面各項正確的是:---BC---int[] y[];
A. y[0] = x[0];
B. y[0] = x;
C. y[0][0] = x[0];
D. y[0][0] = x;
E. y[0] = x[0][0];
注意:[]在變量名之前緊跟的是數據類型,以後定義的每一個變量都會擁有這個[];如果[]在變量名之後,那麼[]只屬於當前的變量。
應用:
遍歷一個二維數組---需要兩個循環
for(int i = 0; i < arr.length; i++){for(int j = 0; j < arr[i].length ; j++){ arr[i][j];}}楊輝三角
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 arr[i][j] = arr[i - 1][j] + arr[i - 1][j - 1];
輸入一個數n,輸出前n行 //從控制檯獲取行數 Scanner s = new Scanner(System.in); int row = s.nextInt(); //根據行數定義好二維數組,由於每一行的元素個數不同,所以不定義每一行的個數 int[][] arr = new int[row][]; //遍歷二維數組 for(int i = 0; i < row; i++){ //初始化每一行的這個一維數組 arr[i] = new int[i + 1]; //遍歷這個一維數組,添加元素 for(int j = 0; j <= i; j++){ //每一列的開頭和結尾元素爲1,開頭的時候,j=0,結尾的時候,j=i if(j == 0 || j == i){ arr[i][j] = 1; } else {//每一個元素是它上一行的元素和斜對角元素之和 arr[i][j] = arr[i -1][j] + arr[i - 1][j - 1]; } System.out.print(arr[i][j] + "\t"); } System.out.println(); }