Java一維二維數組的使用方法詳解(Arrays類方法)
一:數組的概念以及定義,初始化
1.1:數組概念以及定義
數組概念:可以看成是 相同類型元素的一個集合 。
數組定義:三種方法
T [] 數組名 = new T [ N ];例如:int[]arr = new arr[10];
T :表示數組中存放元素的類型
T[]:表示數組的類型
N :表示數組的長度
例如:
int [] array1 = new int [ 10 ]; // 創(chuàng)建一個可以容納 10 個 int 類型元素的數組 double [] array2 = new double [ 5 ]; // 創(chuàng)建一個可以容納 5 個 double 類型元素的數組 String [] array3 = new String [ 3 ]; // 創(chuàng)建一個可以容納 3 個字符串元素的數組
1.2:數組的初始化主要有兩種:動態(tài)初始化以及靜態(tài)初始化
1.靜態(tài)初始化和動態(tài)初始化一步完成
數組動態(tài)初始化:在創(chuàng)建數組時,直接指定數組中元素的個數
int [] array = new int [ 10 ];這種初始化,這個arr數組里面的值都為0;
靜態(tài)初始化:在創(chuàng)建數組時不直接指定數據元素個數,而直接將具體的數據內容進行指定
靜態(tài)初始化雖然沒有指定數組的長度,編譯器在編譯時會根據 {} 中元素個數來確定數組的長度
語法格式: T[] 數組名稱 = {data1, data2, data3, ..., datan};
例如:
int [] array1 = new int []{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 }; double [] array2 = new double []{ 1.0 , 2.0 , 3.0 , 4.0 , 5.0 }; String [] array3 = new String []{ "hell" , "Java" , "!!!" };
靜態(tài)初始化可以省略可以省去后面的new int[];
直接就是 int [] array1 = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
但是這種初始化是嚴令禁止的: int [] array1 = new int [10]{ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };, 編譯器會報錯誤
2.同時靜態(tài)初始化和動態(tài)初始化也可以分為兩步:
int [] array1 ; array1 = new int [ 10 ]; int [] array2 ; array2 = new int []{ 10 , 20 , 30 }; // 注意省略格式不可以拆分, 否則編譯失敗 // int[] array3; // array3 = {1, 2, 3}; 這樣不可以,?。?!只能在定義的時候進行賦值
1.如果沒有對數組進行初始化,數組中元素有其默認值:
2.如果數組中存儲元素類型為引用類型,默認值為null
二:數組的使用:
1.1:數組的訪問:
數組下表訪問不能越界:
int [] array = { 1 , 2 , 3 }; System . out . println ( array [ 3 ]); // 數組中只有 3 個元素,下標一次為: 0 1 2 , array[3] 下標越界
數組越界異常
1.2:數組遍歷
1.一般C中我們都是循環(huán)遍歷:但是java中注意:在數組中可以通過 數組對象.length 來獲取數組的長度
int [] array = new int []{ 10 , 20 , 30 , 40 , 50 }; for ( int i = 0 ; i < array . length ; i ++ ){ System . out . println ( array [ i ]); }
2.java也可以使用for-each遍歷數組:
int [] array = { 1 , 2 , 3 }; for ( int x : array ) { System . out . println ( x ); }
2:數組是引用類型
2.1:要了解數組首先,要了解引用到底是什么?
在java里 數據類型分為兩大類:基本數據類型(Primitive Types)和引用數據類型(Reference Types)。引用數據類型是相對于基本數據類型而言的,它們不是直接在內存中存儲數據值,而是存儲數據的引用(或者說是指向數據的內存地址)。
Java中的引用數據類型主要包括以下幾類:
類,數組,枚舉,接口,注解
我們現在現在需要注意這兩項:
類(Class Types):類是Java程序的基本構建塊,用于創(chuàng)建對象。每個對象都是類的一個實例,而類本身就是一種引用數據類型。你可以定義自己的類來封裝數據和邏輯,Java標準庫中也提供了大量的類供我們使用。
數組(Array Types):數組是一種特殊的引用類型,用于存儲固定大小的同類型元素。數組可以是基本數據類型的數組,也可以是引用數據類型的數組(比如對象數組或另一個數組的數組)。
2.2:初始JVM的內存分布:
內存是一段連續(xù)的存儲空間,主要用來存儲程序運行時數據的。比如:
1. 程序運行時代碼需要加載到內存
2. 程序運行產生的中間數據要存放在內存
3. 程序中的常量也要保存
4. 有些數據可能需要長時間存儲,而有些數據當方法運行結束后就要被銷毀
如果對內存中存儲的數據不加區(qū)分的隨意存儲,那對內存管理起來將會非常麻煩。比如:
因此 JVM 也對所使用的內存按照功能的不同進行了劃分:
- 程序計數器 (PC Register): 只是一個很小的空間, 保存下一條執(zhí)行的指令的地址
- 虛擬機棧(JVM Stack): 與方法調用相關的一些信息,每個方法在執(zhí)行時,都會先創(chuàng)建一個棧幀,棧幀中包含 有:局部變量表、操作數棧、動態(tài)鏈接、返回地址以及其他的一些信息,保存的都是與方法執(zhí)行時相關的一 些信息。比如:局部變量。當方法運行結束后,棧幀就被銷毀了,即棧幀中保存的數據也被銷毀了。
- 本地方法棧(Native Method Stack): 本地方法棧與虛擬機棧的作用類似. 只不過保存的內容是Native方法的局 部變量. 在有些版本的 JVM 實現中(例如HotSpot), 本地方法棧和虛擬機棧是一起的
- 堆(Heap): JVM所管理的最大內存區(qū)域. 使用 new 創(chuàng)建的對象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} ),
- 堆是隨著程序開始運行時而創(chuàng)建,隨著程序的退出而銷毀,堆中的數據只要還有在使用,就不會被銷毀。
- 方法區(qū)(Method Area): 用于存儲已被虛擬機加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數據. 方法編譯出的的字節(jié)碼就是保存在這個區(qū)域
- 現在我們只簡單關心堆 和 虛擬機棧這兩塊空間,后序JVM中還會更詳細介紹。
2.3基本類型變量與引用類型變量的區(qū)別
基本數據類型創(chuàng)建的變量,稱為基本變量,該變量空間中直接存放的是其所對應的值;
引用數據類型創(chuàng)建的變量,一般稱為對象的引用,存儲的是對象所在空間的地址的變量。
從上圖可以看到, 引用變量并不直接存儲對象本身,可以簡單理解成存儲的是對象在堆中空間的起始地址。通過該
地址,引用變量便可以去操作對象 。有點類似 C 語言中的指針,但是 Java 中引用要比指針的操作更簡單。
再看一個例子:
2.4:空指針:null
null 在 Java 中表示 " 空引用 " , 也就是一個不指向對象的引用 .
int [] arr = null ; System . out . println ( arr [ 0 ]); // 執(zhí)行結果 Exception in thread "main" java . lang . NullPointerException at Test . main ( Test . java : 6 )
null 的作用類似于 C 語言中的 NULL ( 空指針 ), 都是表示一個無效的內存位置 . 因此不能對這個內存進行任何讀寫操 作. 一旦嘗試讀寫 , 就會拋出 NullPointerException.
注意 : Java 中并沒有約定 null 和 0 號地址的內存有任何關聯
3:數組應用場景:
3.1:數組作為函數參數:一張圖弄懂
總結 : 所謂的 " 引用 " 本質上只是存了一個地址(還不是真的內存地址) . Java 將數組設定成引用類型 , 這樣的話后續(xù)進行數組參數傳參 ,
其實只是將數組的地址傳入到函數形參中. 這樣可以避免對整個數組的拷貝 ( 數組可能比較長 , 那么拷貝開銷就會很大 ).
3.2:數組作為函數的返回值
public class Test { public static int[] func(){ int []array = new int[]{1,2,3,4,5}; return array; } 實話說這個array數組是個臨時變量,在C里面func返回時會被銷毀,但是在java里面這個還是一直存在的就不會銷毀 public static void main(String[] args) { int[] ret = func(); for (int i = 0; i < ret.length; i++) { System.out.println(ret[i]); } } }
4:數組練習:
4.1:數組轉化為字符串Arrays.toString
public static String myToString(int[] arr) { String ret = "["; for (int i = 0; i < arr.length; i++) { ret += arr[i]; if (i != arr.length - 1) { ret += ","; } else { ret += "]"; } } return ret; } public static void main(String[] args) { int[] arr = {1, 2, 3, 4}; String ret = myToString(arr); System.out.println(ret); } }
注意ret是String類型,每次都是ret+=……,最后直接打印
但是 Arrays.toString這個方法直接幫我們數組轉化為字符串:
4.2:拷貝方法:Arrays.copyOf Arrays.copyOfRange
巧了,我們java里面已經幫我們實現好了:Arrays.copyOf這個方法(這個方法里面的參數(換個類型)還是有很多的,一起構成了方法的重載)
public static void main(String[] args) { //Arrays.copyOf(),Arrays.copyOfRange() int[] arr = {1, 2, 3, 4}; int[] copy = Arrays.copyOf(arr, arr.length * 2); //并且這里我們還可以進行兩倍的拷貝,因為這個數組沒有長度嘛,不用考慮越界的問題 System.out.println(Arrays.toString(copy)); <strong>還可以選擇拷貝:</strong> int[] copy2 = Arrays.copyOfRange(arr, 1, 2);但是這個是從arr數組內部拷過來的 System.out.println(Arrays.toString(copy2)); }
這里大家可以發(fā)現打印的有12個因為是[1,13)左閉右開,,但是arr從1開始里面只有3個數,然后就只能copy3個數然后補0
那這些方法的源碼是怎么實現的呢:大家可以看我這張圖
但是源代碼實現的話又會有一些的的問題:就不能拷貝上述的12個了
我們盡量還是用Arrays.copyOfRange這個方法
注意:
數組當中存儲的是基本類型數據時,不論怎么拷貝基本都不會出現什么問題,但如果存儲的是引用數據類 型,拷貝時需要考慮深淺拷貝的問題,關于深淺拷貝在后續(xù)詳細給大家介紹
4.3:二分查找以及排序方法:
二分查找:針對 有序數組 ,返回的值返回的是最后一次的位置left然后 -(left+1)
所以說按下面這個數組,key每次都>10的話,每次返回都是-9
這是我模仿源碼的方法寫的
public class Test { public static void main(String[] args) { int []arr = {1,2,3,4,5,6,7,8,9}; int key =7; int ret = binarySearch(arr,arr.length,key); System.out.println(ret); } public static int binarySearch(int []arr,int sz,int key){ int left = 0; int right = sz-1; while(left < right){ int mid = (left +right)>>>1;//這個右移一位就很秒 if(arr[mid] < key){ left = mid + 1; } else if(arr[mid]>key){ right = mid -1; }else{ return mid; } } return -(left+1); } }
源碼:
但是如果不是有序地呢,我們可以自己實現一個冒泡排序 以及配合的找數字的,但是java里面已經幫我們實現的有方法了——Arrays.sort
以及配合找數字的Arrays.binarySearch
不過返回的值就是拍完序之后的位置了,這個一定要注意?。?!
二分查找優(yōu)點:針對一個長度為 10000 個元素的數組查找 , 二分查找只需要循環(huán) 14 次就能完成查找 . 隨著數組元素個數 越多, 二分的優(yōu)勢就越大 .
4.4:填充方法以及比較方法:
填充也可以指定范圍:java 太妙啦!??!
4.5:數組求平均值
代碼兩個注意點
1:首先使用 for -each遍歷數組時,這里的X其實就是數組里面的值
2:最后求平均值一定要強轉成double 類型
public static void main(String[] args) { int[] arr = {1,2,3,4,5,6}; System.out.println(avg(arr)); } public static double avg(int[] arr) { int sum = 0; for (int x : arr) { sum += x;//注意這個 } return (double)sum / (double)arr.length;//注意 }
三:二維數組的使用
1.二維數組的4種定義方式
二維數組是特殊的一維數組
二維數組的定義方法:一般就是這三種
int [][] array = {{1,2,3},{4,5,6}}; int [][] array1 = new int[][]{{1,2,3},{4,5,6}}; int [][] array2 = new int[2][3];
但是二維數組還可以不指定列,只指定行(和C語言相反)(第四種)
int [][] array = new int[2][]; String ret = Arrays.toString(array); System.out.println(ret);
(這個時候就相當于,只初始化了兩個值,array[0],array[1],他們兩個的值默認都是null,(這個時候就完全可以看出來array(二維數組就是特殊的一維數組)))
然后我可以這樣給他賦值
int [][] array = new int[2][]; array[0] = new int[]{1,2,3}; array[1] = new int[]{1,2,3,4,5,6};
2.二維數組的遍歷:
我們上述描述過了一維數組(array)的長度是array.length,我們現在又知道了二維數組又是特殊的一維數組(譬如上述的array[2][],那么它的長度就是array.length,它經過初始化之后array[1].length就是3)
那么我們有了上述的知識之后就可以寫出下面的代碼
int [][] array = new int[][]{{1,2,3},{4,5,6}}; for (int i = 0; i < array.length; i++) { for (int j = 0; j < array[i].length; j++) { System.out.print(array[i][j]+" "); } System.out.println();// 打印一行換行 }
3.二維數組的打印
那我們這樣打印呢?
int [][] array = new int[][]{{1,2,3},{4,5,6}}; System.out.println(array[0]); System.out.println(array[1]);
打印的不是實際的地址是經過修改的地址,實際上是
最后調用的是 toString方法
再看看接下來打印的是什么呢?
int [][] array = new int[][]{{1,2,3},{4,5,6}}; System.out.println(array[0]); System.out.println(array[1]); System.out.println("============="); System.out.println(Arrays.toString(array[0])); System.out.println(Arrays.toString(array[1])); System.out.println("============="); System.out.println(array[0].length); System.out.println(array[1].length); System.out.println("============="); System.out.println(array.length); System.out.println("=============");
這個呢?
int [][] array = new int[][]{{1,2,3},{4,5,6}}; System.out.println(Arrays.toString(array)); System.out.println(Arrays.deepToString(array));
上述
總結
到此這篇關于Java一維二維數組的使用方法的文章就介紹到這了,更多相關Java一維二維數組使用方法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java訪問修飾符public、private、protected及默認訪問權限詳解
這篇文章主要介紹了Java訪問修飾符public、private、protected及默認訪問權限的相關資料,每種修飾符都有其特定的使用場景,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2025-01-01java.lang.OutOfMemoryError: Metaspace異常解決的方法
這篇文章主要介紹了java.lang.OutOfMemoryError: Metaspace異常解決的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-03-03java項目中常用指標UV?PV?QPS?TPS含義以及統計方法
文章介紹了現代Web應用中性能監(jiān)控和分析的重要性,涵蓋了UV、PV、QPS、TPS等關鍵指標的統計方法,并提供了示例代碼,同時,文章還討論了性能優(yōu)化和瓶頸分析的策略,以及使用Grafana等可視化工具進行監(jiān)控與告警的重要性2025-01-01使用Mybatis Generator結合Ant腳本快速自動生成Model、Mapper等文件的方法
這篇文章主要介紹了使用Mybatis Generator結合Ant腳本快速自動生成Model、Mapper等文件的方法的相關資料,需要的朋友可以參考下2016-06-06