1.了解數(shù)組
數(shù)組被芳,大家都不陌生,數(shù)組對于每一門編程語言都是重要的數(shù)據(jù)結(jié)構(gòu)之一爹土,當(dāng)然不同編程語言對于數(shù)組的應(yīng)用和實現(xiàn)也稍有不同评姨。
那么讓我們了解一下Java語言提供的數(shù)組难述。
1.1.什么是數(shù)組?
概念:數(shù)組是具有相同數(shù)據(jù)類型且按一定次序排列的的一組變量的集合體吐句。即:
1.存儲多個數(shù)據(jù)胁后。
2數(shù)組中的每個元素具有相同數(shù)據(jù)類型。
3從內(nèi)存結(jié)構(gòu)的角度理解:數(shù)組在內(nèi)存中是一段連續(xù)的內(nèi)存空間嗦枢,即在內(nèi)存中連續(xù)存儲攀芯。
4.數(shù)據(jù)類型可以是任何數(shù)據(jù)類型,包括基本類型和引用類型文虏。
簡而言之,定義一個數(shù)組就是一次定義多個變量侣诺。
1.2.什么是數(shù)組元素?
構(gòu)成一個數(shù)組的每一個數(shù)據(jù)稱為數(shù)組元素氧秘。
1.3.什么是數(shù)組長度年鸳?
數(shù)組中元素的個數(shù)叫做數(shù)組長度,也叫作數(shù)組大小丸相。
獲取數(shù)組長度的方法:數(shù)組名.length
數(shù)組大小是在為數(shù)組元素分配內(nèi)存時確定的大小搔确,大小不可改變。
1.4.什么是數(shù)組下標(biāo)?
下標(biāo)是數(shù)組元素在數(shù)組中的位置膳算。下表也叫索引( index)座硕。
在一個數(shù)組中,數(shù)組下標(biāo)是用整數(shù)表示的畦幢,從0開始坎吻,依次累加1,直到數(shù)組長度-1宇葱。即:
下標(biāo)的界限 0 到 數(shù)組長度-1瘦真。
下標(biāo)如果為負(fù)數(shù),或者下標(biāo)超過了數(shù)組大小-1黍瞧,此時會發(fā)生數(shù)組下標(biāo)越界诸尽。(ArrayIndexOutOfbounds)
1.5.數(shù)組的數(shù)據(jù)結(jié)構(gòu)(線性表):
線性表,全名為線性存儲結(jié)構(gòu)印颤。使用線性表存儲數(shù)據(jù)的方式可以這樣理解您机,即“把所有數(shù)據(jù)用一根線兒串起來,再存儲到物理空間中”年局。
如下圖就是線性表的存儲結(jié)構(gòu):
2.使用數(shù)組
根據(jù)數(shù)組的維度际看,可以將其分為一維數(shù)組、二維數(shù)組和多維數(shù)組等
2.1.使用數(shù)組的步驟:
1.定義數(shù)組(數(shù)組的聲明)
2.為數(shù)組元素分配內(nèi)存
3.數(shù)組元素初始化
4.使用數(shù)組
2.1.1.定義數(shù)組(聲明數(shù)組):
定義數(shù)組的兩種語法規(guī)則:
1.數(shù)據(jù)類型 [ ] 數(shù)組名; (推薦)
2.數(shù)據(jù)類型 數(shù)組名[ ] ;
例如:
int []score;
int score[];
1.數(shù)組是什么數(shù)據(jù)類型矢否,數(shù)組是元素就是什么數(shù)據(jù)類型仲闽。
2.數(shù)組的特征是[ ]([ ]表示數(shù)組)
3.數(shù)組是引用類型。
定義數(shù)組的本質(zhì)就是向JVM申請內(nèi)存僵朗,JVM將內(nèi)存劃分成幾個區(qū)域赖欣,其中包括堆和棧,不同的區(qū)域儲存不同類型的數(shù)據(jù)验庙。
定義數(shù)組時顶吮,JVM將數(shù)組的名稱存儲在棧中,棧是一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)粪薛,因此數(shù)組名稱在棧中悴了。數(shù)組是引用類型,因此數(shù)組名稱的默認(rèn)值是null违寿。
2.1.2.為數(shù)組元素分配內(nèi)存:
聲明一個數(shù)組時僅為數(shù)組指定了數(shù)組名稱和元素的類型让禀,并未指定元素的個數(shù),沒有為數(shù)組元素分配內(nèi)存陨界。因為沒有為數(shù)組元素分配內(nèi)存,此時無法使用數(shù)組存儲數(shù)據(jù)痛阻。要讓系統(tǒng)為數(shù)組元素分配內(nèi)存菌瘪,必須要指明數(shù)組元素的個數(shù),并通過new運(yùn)算符為數(shù)組元素分配內(nèi)存。
為數(shù)組元素分配內(nèi)存的語法格式:
數(shù)組名=new 數(shù)據(jù)類型[數(shù)組長度]
例如:score=new int[4]俏扩;
定義數(shù)組和為數(shù)組元素分配內(nèi)存糜工,這兩步可以合并一起寫,例:
int [ ]score=new int[4];
(因為數(shù)據(jù)類型為int類型录淡,此時還未為數(shù)組元素初始化捌木,所以數(shù)組元素的默認(rèn)值是0。)
內(nèi)存分配如下圖所示:
2.1.3.數(shù)組元素初始化:
數(shù)組聲明并為數(shù)組元素分配內(nèi)存空間完成后嫉戚,必須為數(shù)組元素初始化(初始化就是第一次賦值的意思)后刨裆,才能使用數(shù)組元素。如果沒有為數(shù)組元素初始化彬檀,那么數(shù)組元素為默認(rèn)值帆啃。各種數(shù)據(jù)類型數(shù)組元素的默認(rèn)值見表:
數(shù)組元素基本類型 | 默認(rèn)初始值 |
---|---|
byte,int窍帝,short 努潘,long | 0 |
float,double | 0.0 |
char | '\u0000' |
boolean | false |
引用數(shù)據(jù)類型 | null |
可以通過數(shù)組下標(biāo)對數(shù)組元素初始化坤学,例如:
array[0]=65; //表示數(shù)組的第一個數(shù)組元素賦值為65
數(shù)組的幾種初始化方式:
1.靜態(tài)初始化(靜態(tài)初始化時, {}中數(shù)據(jù)類型必須與[]前數(shù)據(jù)類型一致疯坤。)
數(shù)據(jù)類型 [ ] 數(shù)組名稱 = new 數(shù)據(jù)類型[ ]{數(shù)組元素1,數(shù)組元素2深浮,數(shù)組元素3…};
或者 压怠,
數(shù)據(jù)類型 [ ] 數(shù)組名稱 = {數(shù)組元素1,數(shù)組元素2略号,數(shù)組元素3…};
2.動態(tài)初始化
數(shù)據(jù)類型 [ ] 數(shù)組名稱=new 數(shù)據(jù)類型[數(shù)組長度];
定義數(shù)組刑峡、為數(shù)組元素分配內(nèi)存、數(shù)組元素初始化玄柠,可以放在一步寫突梦,例如:
int [ ]score=new int[4];
int [ ]score=new int[]{84,45,96,78};
int [ ]score={84,45,96,78}
2.1.4使用數(shù)組:
使用數(shù)組通常都是求數(shù)組中的最大值、最小值羽利、總和宫患、平均值、遍歷數(shù)組元素这弧、數(shù)組元素排序娃闲、數(shù)組元素中元素的數(shù)量等操作。
我們可以通過實例來理解如何使用數(shù)組:
2.1.4.1.最大值匾浪,最小值皇帮,平均值,求和:
例:班級5個學(xué)生蛋辈,創(chuàng)建一個成績的數(shù)據(jù)属拾,統(tǒng)計最大值将谊,最小值,平均值渐白,求和:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//定義數(shù)組尊浓、為數(shù)組元素分配內(nèi)存
int[] scores = new int[5];
//數(shù)組元素初始化
for (int i = 0; i < scores.length; i++) { //遍歷數(shù)組
System.out.printf("請輸入第%d位同學(xué)的成績:", (i + 1));
scores[i] = scanner.nextInt();
}
//使用數(shù)組
int max = scores[0];
int min = scores[0];
for (int i = 1; i < scores.length; i++) {
if (max < scores[i]) { //求最大值
max = scores[i];
}
if (min > scores[i]) { //求最小值
min = scores[i];
}
}
System.out.println("成績最大值為:" + max);
System.out.println("成績最小值為:" + min);
//求和
int sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
System.out.println("總分為:" + sum);
//平均值
System.out.println("平均分為:" + sum / scores.length);
}
2.1.4.2.用增強(qiáng)for循環(huán)遍歷數(shù)組:
jdk1.5版本及其之后的版本提供了增強(qiáng)for循環(huán)語句,用來對數(shù)組和集合中的數(shù)據(jù)進(jìn)行遍歷纯衍,增強(qiáng)for循環(huán)的語法規(guī)則:
for(元素類型 變量名:要循環(huán)的數(shù)組或集合){
.......
}
1.元素類型是指數(shù)組或集合中的元素的類型栋齿。
2.變量名在循環(huán)時用來保存每個元素的值。
3.冒號后面是要遍歷的數(shù)組或集合的名稱襟诸。例如:
public static void main(String[] args) {
int []arrays={45,79,54,87};
for (int a:arrays) {
System.out.print(a); //遍歷arrays數(shù)組
}
}
2.1.4.3.數(shù)組元素排序:
常用的排序算法:冒泡排序瓦堵、選擇排序、插入排序励堡、快速排序谷丸、希爾排序、歸并排序应结、快速排序刨疼、基數(shù)排序、堆排序鹅龄、計數(shù)排序揩慕、桶排序、二叉樹排序扮休。前四種是比較常用的算法迎卤,而冒泡排序是最重要的一種排序算法。
冒泡排序:
public static void main(String[] args) {
//冒泡排序
int []score = {45,74,68,58,89};
for (int i = 0; i < score.length-1; i++) {
for (int j = 0; j < score.length-i-1; j++) {
if(score[j]>score[j+1]){
int tmp = score[j];
score[j]=score[j+1];
score[j+1]= tmp;
}
}
}
System.out.println(Arrays.toString(score));
}
選擇排序:
選擇排序
public static void main(String[] args) {
//選擇排序
int[] arr ={45,74,68,58,89};
for (int i = 0; i < arr.length-1; i++) {//每次循環(huán)都會找出最小的數(shù)
int minIndex = i;//記錄最小數(shù)的下標(biāo)
int min = arr[i];//記錄最小數(shù)
for(int j = i+1; j < arr.length; j++){//每次循環(huán)都會找出最小的數(shù)
if (arr[j] < min){//如果當(dāng)前數(shù)比最小數(shù)小玷坠,則更新最小數(shù)
min = arr[j];//更新最小數(shù)
minIndex = j;//更新最小數(shù)的下標(biāo)
}
}
int tmp = arr[i];
arr[i] = arr[minIndex];//將最小數(shù)放到最前面
arr[minIndex] = tmp;
}
System.out.println(Arrays.toString(arr));
}
插入排序:
public static void main(String[] args) {
//插入排序
int[] arr ={45,74,68,58,89};
for (int i = 1; i < arr.length; i++) {
int j = i;
while (j > 0){
if (arr[j] < arr[j-1]){
int temp ;
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
j--;
}else {
break;
}
}
}
System.out.println(Arrays.toString(arr));
}
快速排序:
快速排序
public static void main(String[] args){
//快速排序
int[] arr ={45,74,68,58,89};
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr,int first,int last){
if (first >= last) {
return;
}
int low = first;
int high = last;
//如果mid_value = arr[last]的話蜗搔,下面的兩個內(nèi)部while循環(huán)就要換一下順序
int mid_value = arr[first];
while (low < high){
while (low < high && arr[high] >= mid_value){
high-=1;
}
arr[low] = arr[high];
while (low < high && arr[low] < mid_value){
low +=1;
}
arr[high] = arr[low];
}
arr[high] = mid_value;
//遞歸對左右兩邊的數(shù)據(jù)排序
quickSort(arr,first,low-1);
quickSort(arr,low+1,last);
}
2.1.4.4.查找數(shù)組元素:
二分查找:
public static void main(String[] args) {
int num[] = {3, 9, 12, 48, 67};
int index = binarySearch(num, 9);
System.out.println(index);
}
public static int binarySearch(int[] srcArray, int des) {
//定義初始最小、最大索引
int start = 0;
int end = srcArray.length - 1;
//確保不會出現(xiàn)重復(fù)查找八堡,越界
while (start <= end) {
//計算出中間索引值
int middle = (end + start) >>> 1;//防止溢出
if (des == srcArray[middle]) {
return middle;
//判斷下限
} else if (des < srcArray[middle]) {
end = middle - 1;
//判斷上限
} else {
start = middle + 1;
}
}
//若沒有樟凄,則返回-1
return -1;
}
3.數(shù)組的工具類java.util.Arrays類
3.1.比較兩個數(shù)組是否相等:equals(array1,array2);
public static void main(String[] args) {
int []arr1 = {10,50,40,30};
int []arr2 = {10,50,40,30};
int []arr3 = {60,50,85};
System.out.println(Arrays.equals(arr1, arr2));//判斷arr1與arr2的長度及元素是否相等
System.out.println(Arrays.equals(arr1, arr3));//判斷arr1與arr3的長度及元素是否相等
}
3.2.對數(shù)組元素進(jìn)行升序排序:sort(arr);
數(shù)組全部排序:
public static void main(String[] args){
int []arr1 = {10,50,40,30};
Arrays.sort(arr1);
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
}
數(shù)組指定下標(biāo)范圍排序:
public static void main(String[] args){
int []arr1 = {10,50,40,30,89,67,4,678};
Arrays.sort(arr1,3,arr1.length-1);
for (int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
}
3.3.將數(shù)組轉(zhuǎn)換成字符串:toString(arr);
public static void main(String[] args){
int []arr1 = {10,50,40,30,89,67,4,678};
Arrays.sort(arr1);
System.out.println( Arrays.toString(arr1));
}
3.4.將數(shù)組所有元素賦值為相同的值:fill(arr,key);
public static void main(String[] args){
int []arr1 = {10,50,40,30,89,67,4,678};
Arrays.fill(arr1,30);
System.out.println( Arrays.toString(arr1));
}
運(yùn)行結(jié)果:
[30, 30, 30, 30, 30, 30, 30, 30]
3.5.將數(shù)組賦值成一個長度為設(shè)定值的新數(shù)組:copyOf(arr1,arr2.length)
public static void main(String[] args){
int []arr1 = new int[] {10,50,40,30 };
//將arr1復(fù)制成長度為3的新數(shù)組arr2
int []arr2 = Arrays.copyOf(arr1,3);
System.out.println(Arrays.toString(arr2));
//將arr1復(fù)制成長度為30的新數(shù)組arr3
int []arr3 = Arrays.copyOf(arr1,30);
System.out.println(Arrays.toString(arr3));
}
運(yùn)行結(jié)果:
[10, 50, 40]
[10, 50, 40, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
3.6.查詢元素在數(shù)組中的下標(biāo):binarySearch(arr[],index);
public static void main(String[] args){
int []arr = new int[] {10,50,40,30 };
Arrays.sort(arr);//排序后 10 30 40 50 90
int index = Arrays.binarySearch(arr, 10);
System.out.println(index);
index = Arrays.binarySearch(arr, 0);
System.out.println(index);
index = Arrays.binarySearch(arr, 45);
System.out.println(index);
index = Arrays.binarySearch(arr, 90);
System.out.println(index);
}
運(yùn)行結(jié)果
0
-1
-4
-5
分析:
- 若找到了數(shù)據(jù),則返回該數(shù)據(jù)的下標(biāo);若找不到數(shù)據(jù)兄渺,則返回負(fù)數(shù)缝龄,其值為該數(shù)據(jù)在數(shù)組中排序的位置
4.二維數(shù)組
在實際運(yùn)用中,三維及其以上的數(shù)組使用的很少挂谍,主要使用二維數(shù)組叔壤。
使用二維數(shù)組的步驟與使用一維數(shù)組的步驟相同:1.定義數(shù)組(數(shù)組的聲明)、2.為數(shù)組元素分配內(nèi)存口叙、3.數(shù)組元素初始化炼绘、4.使用數(shù)組
4.1.定義二維數(shù)組(數(shù)組的聲明):
定義二維數(shù)組的兩種語法規(guī)則:
1.數(shù)據(jù)類型 [ ] [ ]數(shù)組名;
2.數(shù)據(jù)類型 數(shù)組名[ ] [ ];
4.2.為二維數(shù)組元素分配內(nèi)存:
二維數(shù)組實際上是一個一維數(shù)組,這個一維數(shù)組的每一個元素又是一個一維數(shù)組妄田。例如:
int [ ] [ ]s=new int[3] [3];
4.3.二維數(shù)組元素初始化:
示例:
int arr[ ] [ ]=new int[ ] [ ]{{1,2,3}俺亮,
{4,5,6}仗哨,
{7,8,9},
}铅辞;
int arr[ ] [ ]={{1,2,3},
{4,5,6}萨醒,
{7,8,9}斟珊,
};
4.4.使用二維數(shù)組:
讓我們看一個小例子便于理解:
public static void main(String[] args) {
//創(chuàng)建定義二維數(shù)組
int[][] scores = new int[3][4];
//創(chuàng)建Scanner
Scanner input = new Scanner(System.in);
//給每個二維數(shù)組中的一維數(shù)組賦值
for(int i = 0; i < scores.length; i++){
for(int j = 0; j < scores[i].length; j++){
System.out.println("輸入整數(shù)");
scores[i][j] = input.nextInt();
}
}
//查看二維數(shù)組中的一維元素
for (int i = 0; i < scores.length; i++) {
System.out.println(Arrays.toString(scores[i]));
}
}