?
我的個人博客主頁:如果’'真能轉(zhuǎn)義1??說1??的博客主頁
關(guān)于Java基本語法學(xué)習(xí)---->可以參考我的這篇博客:《我在VScode學(xué)Java》
在Java中,數(shù)組被看作是對象。數(shù)組是用new操作符創(chuàng)建的。一個數(shù)組變量實際上是一個包含數(shù)組引用的變量。
零._.在Java中_什么是數(shù)組
1.>Java 數(shù)組是一種數(shù)據(jù)結(jié)構(gòu),存儲一組相同類型的數(shù)據(jù)。
(1)Java和其他高級語言都提供了一種使用一個統(tǒng)一的數(shù)組名和不同的下標(biāo)來唯一確定數(shù)組 (array)中的元素的數(shù)據(jù)結(jié)構(gòu)。
(2)可以用一個標(biāo)識符封裝存儲一個元素個數(shù)固定且元素類型相同的基本類型數(shù)據(jù)序列或者對象序列。(是一個簡單的線性序列,因此訪問速度很快。)
[1] 數(shù)組在Java 中是一個對象,可以通過聲明一個數(shù)組變量來創(chuàng)建。
【在Java中,聲明一個數(shù)組變量需要指定數(shù)組的類型和名稱,然后使用方括號指定數(shù)組的大小。聲明一個包含5個整數(shù)的數(shù)組 int[] myArray = new int[5];
】
[2] 數(shù)組變量包含一個指向數(shù)組對象的引用,而數(shù)組對象包含實際的數(shù)據(jù)。
數(shù)組變量和數(shù)組對象之間的關(guān)系:
當(dāng)你創(chuàng)建了一個數(shù)組時,實際上是在內(nèi)存中分配了一塊連續(xù)的空間來存儲數(shù)據(jù),并將數(shù)組變量指向該空間的引用存儲在變量中。在下文會講述在Java中數(shù)組是怎么存儲的方式。數(shù)組是一種對象類型,因此可以使用new關(guān)鍵字來創(chuàng)建一個數(shù)組對象 int[] myArray = new int[5];
2>引用數(shù)據(jù)類型1、默認(rèn)值、數(shù)組長度:
【1】Java數(shù)組是引用數(shù)據(jù)類型,長度屬性為 length。
【2】Java數(shù)組下標(biāo)是從零開始的,Java數(shù)組下標(biāo)訪問運算符[ ].
【3】數(shù)組元素的默認(rèn)值:
對于基本數(shù)據(jù)類型 0,0.0,‘\u000’
對于引用元素數(shù)據(jù)類型string,object等為 null。
對于Boolean類型,為false
【4】數(shù)組的長度:數(shù)組名.length。
數(shù)組的元素是通過索引訪問。索引從 0 開始,索引值從 0 到 array.length-1。
默認(rèn)值
int[] intArray = new int[5];
System.out.println(intArray[0]); // 輸出0
double[] doubleArray = new double[5];
System.out.println(doubleArray[0]); // 輸出0.0
char[] charArray = new char[5];
System.out.println(charArray[0]); // 輸出空字符
boolean[] boolArray = new boolean[5];
System.out.println(boolArray[0]); // 輸出false
String[] strArray = new String[5];
System.out.println(strArray[0]); // 輸出null
3>存儲同種數(shù)據(jù)類型 – >考慮隱式轉(zhuǎn)換
根據(jù)不同類型選擇不同類型的數(shù)組存儲同種數(shù)據(jù)類型的多個值。數(shù)組在存儲數(shù)據(jù)的時候,需要結(jié)合隱式轉(zhuǎn)換考慮。
需要做到保持?jǐn)?shù)組容器的類型,和存儲的數(shù)據(jù)類型保持一致
例如: int類型的數(shù)組容器 ( byte short int )[缺點 范圍要把控]
例如: double類型的數(shù)組容器double( byte short int long float double )
4>動靜態(tài)初始化
動態(tài):先知道指定數(shù)組長度,后續(xù)可由需要進(jìn)行數(shù)值填寫
new一個
靜態(tài):給定數(shù)值,系統(tǒng)給計算數(shù)組長度
壹._.一維數(shù)組
1>解釋:
Java的一維數(shù)組是一種數(shù)據(jù)結(jié)構(gòu),用于存儲相同類型的元素。【如:存儲基本數(shù)據(jù)類型(如int,float等)和對象類型(如String,Object等)?!?br> 每個元素都可以通過其索引訪問,索引從0開始以數(shù)組的長度-1結(jié)束2。
2>聲明與初始化
Understanding Java Array Declaration and Initialization.
創(chuàng)建數(shù)組:分配數(shù)據(jù)存儲的物理空間是在堆上 arrayRefVar = new dataType[arraySize];
【1】Array Declaration_聲明數(shù)組:必須先聲明數(shù)組變量,才能在程序中正常使用數(shù)組。
聲明數(shù)組是指創(chuàng)建一個數(shù)組變量,但是并沒有為其分配內(nèi)存空間。例如:int[] myArray;
這里我們聲明了一個名為myArray的整型數(shù)組,但是它并沒有被初始化,也就是說它并沒有被賦值為一個具體的數(shù)組對象。
elementType[] arrayRefVar; // 首選的方法
dataType arrayRefVar[]; // 效果相同,但不是首選方法
double [] douarray;
int inarr[];
在Java語言中,采用 【 數(shù)據(jù)類型 [ ] 數(shù)組名 】的形式,而【數(shù)據(jù)類型 數(shù)組名 [ ] 】是保留了C/C++的形式。如今越來越多的語言的風(fēng)格都采用了第一種的形式了。
【2】Array Initialization_初始化數(shù)組(開始分配空間) —>分為 靜態(tài)初始化和動態(tài)初始化和默認(rèn)初始化三種方式。
初始化數(shù)組是指為數(shù)組分配內(nèi)存空間,并為其賦初值。例如:int[] myArray = new int[]{1, 2, 3};
Java數(shù)組的初始化告訴編譯器數(shù)組的大小和元素的值。這里我們初始化了一個名為myArray的整型數(shù)組,它被賦值為一個包含三個元素的數(shù)組對象,這三個元素的值分別為1、2、3。
數(shù)組可以在聲明時初始化,也可以在之后的代碼中初始化。
(1)靜態(tài)初始化 —>是在編譯時進(jìn)行的。
Java數(shù)組的靜態(tài)初始化是指在聲明數(shù)組時為其分配空間并初始化其元素。這可以通過在聲明數(shù)組時使用花括號來完成,int[] myArray = new int[]{1, 2, 3};
完整格式: 數(shù)據(jù)類型 [] 數(shù)組名 = new 數(shù)據(jù)類型[]{元素1,元素2....};
簡化格式: 數(shù)據(jù)類型 [] 數(shù)組名 =[ 元素1,元素2,元素3...};
//根據(jù)不同類型選擇不同類型的數(shù)組
范例: int[] array=11,22,33);
范例: double []array2 ={ 11.1,22.2,33.3);
獲取地址值與哈希碼---->地址值是十六進(jìn)制的,其轉(zhuǎn)換為十進(jìn)制就是我們的哈希碼
地址值是對象在內(nèi)存中的實際物理地址,是在內(nèi)存中的位置可以通過Java中的System.identityHashCode(Object obj)方法獲取。
地址值的主要作用是在底層實現(xiàn)中進(jìn)行對象的訪問和操作。
哈希碼是根據(jù)對象的內(nèi)容計算出來的一個int類型的值,根據(jù)對象的內(nèi)容計算出來的一個整數(shù)值。
可以通過Java中的Object.hashCode()方法獲取。哈希碼的主要作用是在集合類中進(jìn)行對象的查找和比較,例如HashMap、HashSet等。使用了一個常見的哈希碼實現(xiàn),稱為"乘法散列”。
需要注意的是,哈希碼并不是唯一的,不同的對象可能會有相同的哈希碼。
而地址值是唯一的,每個對象在內(nèi)存中都有一個唯一的地址。
int[] arr = { 1, 2, 3 };
int address = System.identityHashCode(arr);
System.out.println("The address of the array is: " + address);
System.out.println("The address of the array is: " + arr);
第3行輸出的是數(shù)組在內(nèi)存中的地址,而第4行輸出的是數(shù)組中存儲的元素。如果想要獲取數(shù)組在內(nèi)存中的地址,需要使用System.identityHashCode()方法。
//擴(kuò)展:
[D@776ec8df
//解釋一下地址值的格式含義
//[ : 表示當(dāng)前是一個數(shù)組
//D: 表示當(dāng)前數(shù)組里面的元素都是double類型的
//@: 表示一個間隔符號。 (固定格式),@是沒有含義的
//776ec8df: 才是數(shù)組真正的地址值, (十六進(jìn)制)
//平時我們習(xí)慣性的會把這個整體叫做數(shù)組的地址值
地址值的十六進(jìn)制轉(zhuǎn)換為十進(jìn)制就是我們的哈希碼
可以使用Java內(nèi)置的System類中的identityHashCode方法。這個方法返回一個對象的哈希碼,可以用來表示對象的地址值。在你的代碼中,你可以使用以下代碼來獲取myArray數(shù)組的地址值:System.out.println(System.identityHashCode(myArray));
這個地址值是一個哈希碼,不是一個真正的內(nèi)存地址。因此,它不能用來進(jìn)行指針?biāo)阈g(shù)或其他低級操作。
什么是哈希碼:
在Java中,每個對象都有一個默認(rèn)的哈希碼,可以使用hashCode()方法來獲取,默認(rèn)情況下,hashCode()方法返回對象的內(nèi)存地的整教表示形式,但是,可以通過圈蓋hashode()方法來提供自定義哈希碼實現(xiàn)。這個自定義哈希碼應(yīng)該是根據(jù)對條的內(nèi)容計算出來的,而不是根據(jù)對象的內(nèi)存地處。這樣可以確保具有相同內(nèi)容的對象具有相同的哈希碼,從而提高哈希表的性能。以下是一個簡單的Java類,演示如何覆蓋hashCode ()方法來提供自定義哈希碼實現(xiàn):
哈希碼(Hash Code)是指將任意長度的消息壓縮到某一固定長度的消息摘要,通常為一個固定長度的字節(jié)序列。哈希碼通過一種稱為哈希函數(shù)的算法來生成,它將任意長度的消息映射到一個固定長度的消息摘要。哈希碼的特點是唯一性,即不同的消息會生成不同的哈希碼,相同的消息生成的哈希碼也是相同的。哈希碼常用于數(shù)據(jù)加密、數(shù)據(jù)壓縮、數(shù)據(jù)完整性驗證等領(lǐng)域。
運用
System.out.println("The address of the array is: " + address);//681842940
System.out.println("The address of the array is: " + System.identityHashCode(arr[0]));//1392838282
System.out.println("The address of the array is: " + System.identityHashCode(arr[1]));// 523429237
System.out.println("The address of the array is: " + System.identityHashCode(arr[2]));//664740647
為什么不是連續(xù)的
這是因為Java數(shù)組不一定是在內(nèi)存中連續(xù)存儲的。Java數(shù)組是對象,它們在內(nèi)存中的存儲方式取決于Java虛擬機(jī)的實現(xiàn)。在某些情況下,Java虛擬機(jī)可能會將數(shù)組存儲在連續(xù)的內(nèi)存塊中,但在其他情況下,它們可能會被分散存儲在內(nèi)存中的不同位置。因此,您不能假設(shè)Java數(shù)組在內(nèi)存中是連續(xù)存儲的。
注意
在Java中,只有對象和數(shù)組才會有地址值?;绢愋停ɡ鏸nt、boolean等)沒有地址值。
Scanner sc = new Scanner(System.in);
int c = sc.nextInt();
System.out.println(Integer.toHexString(System.identityHashCode(c)));
System.out.println(System.identityHashCode(c));
sc.close();
12
2d98a335
764977973
既然整數(shù)沒有地址值,那為什么還是產(chǎn)生了地址值:
這是因為Java中的所有類型都是對象,包括基本類型。在Java中,基本類型被封裝在對象中,這些對象稱為包裝器類。例如,整數(shù)類型int被封裝在Integer類中。因此,即使你的變量是一個整數(shù)類型,它仍然是一個對象,因此可以使用System.identityHashCode()方法來獲取其地址值。
存放在哪
根據(jù)Java的內(nèi)存模型,對象和數(shù)組是在堆內(nèi)存中分配的,而基本類型和引用變量則是在棧內(nèi)存中分配的。因此,Java中的地址值是指向堆內(nèi)存中的對象或數(shù)組的引用,因此地址值是在堆內(nèi)存中的。
注意事項
在Java中,堆棧是一種數(shù)據(jù)結(jié)構(gòu),用于存儲方法調(diào)用和本地變量。堆棧的地址值是指指向堆棧頂部的指針。每當(dāng)方法被調(diào)用時,一個新的堆棧幀被創(chuàng)建并推入堆棧中。當(dāng)方法返回時,堆棧幀被彈出堆棧。因此,堆棧地址值隨著方法調(diào)用的推入和彈出而變化。
另一方面,堆是用于動態(tài)分配內(nèi)存的區(qū)域。在Java中,所有對象都存儲在堆中。堆中的對象可以通過引用進(jìn)行訪問,而不是直接訪問堆地址值。
因此,堆棧地址值和堆地址值是不同的概念,它們的作用和用途也不同。堆棧地址值用于跟蹤方法調(diào)用和本地變量,而堆地址值用于跟蹤動態(tài)分配的對象。
(2)動態(tài)初始化—>運行時進(jìn)行的。
動態(tài)初始化:初始化時只指定數(shù)組長度,由系統(tǒng)為數(shù)組分配初始值。格式:數(shù)據(jù)類型[]數(shù)組名 = new 數(shù)據(jù)類型數(shù)組長度[];
在創(chuàng)建的時候,由我們自己指定數(shù)組的長度,由虛擬機(jī)給出默認(rèn)的初始化值
在Java中,動態(tài)初始化數(shù)組是指在聲明數(shù)組時,只指定數(shù)組的長度,而不指定數(shù)組元素的值。例如int[] myArray = new int[5];
在這個代碼中,我們聲明了動態(tài)初始化數(shù)組的場景包括:
一個名為myArray的整數(shù)數(shù)組,并指定其長度為5,由于我們沒有指定數(shù)組元素的值,因此Java會自動將所有元素初始化為默認(rèn)值0.
當(dāng)您需要一個具有固定大小的數(shù)組時,但是您不知道數(shù)組元素的值。當(dāng)您需要個具有固定大小的數(shù)組時,并且您知道數(shù)組元素的值,但是這些值在運行時無法確定
在第二種情況下,您可以使用靜態(tài)初始化數(shù)組來指定數(shù)組元素的值。例如:int[] myArray = {1, 2,3,4,5};
在這個代碼中,我們聲明了一個名為myArray的整數(shù)數(shù)組,并指定其元素的值為1、2、3、4和5.
說明
dataType[] arrayName = new dataType[arraySize];
請注意,動態(tài)初始化數(shù)組時,數(shù)組中的元素將自動初始化為其默認(rèn)值。例如,對于整數(shù)數(shù)組,所有元素將初始化為0。如果您想要將數(shù)組中的元素設(shè)置為不同的值,您可以使用循環(huán)或逐個分配值。
使用new關(guān)鍵字動態(tài)初始化數(shù)組時,會在堆中分配一塊內(nèi)存空間,用于存儲數(shù)組元素。如果您多次使用new關(guān)鍵字初始化數(shù)組,則會在堆中分配多個內(nèi)存空間,每個內(nèi)存空間都包含各自的數(shù)據(jù)。
(3)默認(rèn)初始化
默認(rèn)初始化數(shù)組的值取決于數(shù)組的類型。如果數(shù)組是基本類型(如int,double等),則默認(rèn)值為0。如果數(shù)組是對象類型,則默認(rèn)值為null。
【3】靜態(tài)初始化與動態(tài)初始化的區(qū)別
(1)個數(shù)和給定值
動態(tài)初始化是在運行時進(jìn)行的和元素的值都可以在運行時確定,
而在靜態(tài)初始化中,數(shù)組的大小和元素的值都在編譯時確定。
靜態(tài)初始化:手動指定數(shù)組元素,系統(tǒng)會根據(jù)元素個數(shù),計算出數(shù)組的長度。需求中已經(jīng)明確了要操作的具體數(shù)據(jù),直接靜態(tài)初始化即可。int[] arr = (11, 22, 33);
動態(tài)初始化:手動指定數(shù)組長度,由系統(tǒng)給出默認(rèn)初始化值。只明確元素個數(shù),不明確具體數(shù)值,推薦使用動態(tài)初始化int[] arr = new int[5];
只要在定義數(shù)組時就已經(jīng)確定了數(shù)組的元素個數(shù)和元素值,就是靜態(tài)初始化。
而動態(tài)初始化只確定了數(shù)組的長度,而數(shù)組的元素值需要在后續(xù)的代碼中進(jìn)行賦值.
靜態(tài)初始化時就已經(jīng)確定了,不需要在new后面的數(shù)提類型的[]里面寫。
因為在靜態(tài)初始化時,編譯器會根據(jù)你提供的元素個數(shù)自動計算出數(shù)組的長度,因此你只需要在[]里面提供元素即可。
(2)另一個區(qū)別是,動態(tài)初始化可以在運行時更改數(shù)組的大小,而靜態(tài)初始化則不能。
總的來說,動態(tài)初始化和靜態(tài)初始化都是初始化Java數(shù)組的有效方法。它們的主要區(qū)別在于初始化時間和數(shù)組大小是否可以更改
如果您需要向數(shù)組添加后續(xù)元素則應(yīng)該使用動態(tài)初始化
如果您使用靜態(tài)初始化創(chuàng)建Java數(shù)組,則無法向數(shù)組添加后續(xù)元素,因為數(shù)組的大小已經(jīng)在編譯時確定
動態(tài)添加后續(xù)的元素需要什么操作如果您使用動態(tài)初始化創(chuàng)建Java數(shù)組,則可以使用以下代碼向數(shù)組添加后續(xù)元素:
int[] dynamicArray = new int[5];
dynamicArray[0] = 1;
dynamicArray[1] = 2;
dynamicArray[2] = 3
dynamicArray[3] = 4
dynamicArray[4] = 5;
dynamicArray = Arrays.copyof(dynamicArray,10)
dynamicArray[5] = 6;
dynamicArray[6] = 7;
dynamicArray[7] = 8;
dynamicArray[8] = 9;
dynamicArray[9] = 1;
接
在上面的代碼中,我們首先使用動態(tài)初始化創(chuàng)建了一個名為dnamicArray 的整數(shù)數(shù)組,并將其初始化為長度為5的數(shù)組,然后,我們使用索引將1、2、3、4和5添加到數(shù)組中。
下來,我們使用Arrays.copy()方法將數(shù)組的大小更改為10。最后,我們使用索引將6、7、8、9和10添加到數(shù)組中。
請注意,如果您使用靜態(tài)初始化創(chuàng)建Java數(shù)組,則無法向數(shù)組添加后續(xù)元素,因為數(shù)組的大小已經(jīng)在編譯時確定。如果您需要向數(shù)組添加后續(xù)元素,則應(yīng)該使用動態(tài)初始化
使用靜態(tài)初始化創(chuàng)建Java數(shù)組,則無法向數(shù)組添加后續(xù)元素,因為數(shù)組的大小已經(jīng)在編譯時確定的。靜態(tài)初始化是在創(chuàng)建數(shù)組時同時指定數(shù)組大小和元素的過程
。
靜態(tài)初始化創(chuàng)建的數(shù)組大小是固定的,因此無法向數(shù)組添加后續(xù)元素。
(1)如果您需要向數(shù)組添加后續(xù)元素,則應(yīng)該使用動態(tài)初始化。
(2)您可以根據(jù)需要更改size的值,以便在運行時動態(tài)調(diào)整數(shù)組的大小。
數(shù)據(jù)類型[] 數(shù)組名= new 數(shù)據(jù)類型[]{元素1,元素2....};
,叫做靜態(tài)初始化。
爭態(tài)初始化方式。這種方式在定義數(shù)組時就已經(jīng)確定了數(shù)組的元素個數(shù)和元素值,因此也數(shù)據(jù)類型[] 數(shù)組名 = new 數(shù)據(jù)類型[數(shù)組長度]
叫做動態(tài)初始化數(shù)組
其中,數(shù)組長度可以是一個整數(shù),也可以是一個變量。這種方式在定義數(shù)組時只確定了組的長度,而數(shù)組的元素值需要在后續(xù)的代碼中進(jìn)行賦值.
3>動態(tài)分配內(nèi)存
Java還提供了其他的方法,例如ArrayList和LinkedList。這些類允許您在運行時添加和刪除元素,而無需手動管理內(nèi)存分配。
//java.util.Scanner類從用戶讀取輸入。Scanner類允許您從標(biāo)準(zhǔn)輸入讀取用戶輸入。
import java.util.ArrayList;
public class MyClass {
public static void main(String[] args) {
ArrayList<Integer> intList = new ArrayList<Integer>();
intList.add(1);
intList.add(2);
intList.add(3);
System.out.println(intList); // 輸出 [1, 2, 3]
}
}
?
4>處理數(shù)組內(nèi)容
一般使用基本的三大循環(huán)或者 For-Each 循環(huán)。
For-Each 循環(huán)或者加強(qiáng)型循環(huán),它能在不使用下標(biāo)的情況下遍歷數(shù)組。
int[] intArray = {1, 2, 3, 4, 5};
// 使用for-each循環(huán)輸出數(shù)組元素
for (int i : intArray) {
System.out.println(i);
}
不要在進(jìn)行數(shù)組初始化時,既指定數(shù)組的長度,也為每個數(shù)組元素分配初始值,這樣會造成代碼錯誤。
越界訪問數(shù)組 —>警告
警告 越界訪問數(shù)組是經(jīng)常會出現(xiàn)的程序設(shè)計錯誤,它會拋出一個運行錯誤ArrayIndexOut0fBoundsException。
為了避免錯誤的發(fā)生,在使用時應(yīng)確保所使用的下標(biāo)不超過arrayRefVar.length-1。
主要原因:是在循環(huán)中該使用<的地方誤用<=時會犯的錯誤。
?
?
5>方法:
二分查找:
左閉右閉區(qū)間的:
public class BinarySearch {
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
左閉右開區(qū)間的:
public class BinarySearch {
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
return -1;
}
?
排序
?
自帶方法:
長度為0的數(shù)組并非null
(1)Arrays.sort():該方法使用快速排序算法對數(shù)組進(jìn)行排序。時間復(fù)雜度為O(nlogn)。
int[] arr = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
(2)Collections.sort():該方法使用歸并排序算法對列表進(jìn)行排序。時間復(fù)雜度為O(nlogn)
List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5));
Collections.sort(list);
System.out.println(list);
6>一些術(shù)語:
anonymous array (匿名數(shù)組)
array initializer(數(shù)組初始化語法)
binary search (二分查找)
index (下標(biāo))
indexed variable(下標(biāo)變量)
insertion sort (插入排序)
linear search(線性查找)
selection sort (選擇排序)
?
?
7>根據(jù)學(xué)習(xí)和書籍上的內(nèi)容總結(jié)一下:
-
聲明數(shù)組變量并不會給數(shù)組分配任何空間。數(shù)組變量不是基本數(shù)據(jù)類型變量。數(shù)組變量包含的是對數(shù)組的引用。當(dāng)創(chuàng)建一個數(shù)組時,若它的元素是基本數(shù)據(jù)類型的數(shù)值,那么該數(shù)組的初始值的默認(rèn)值和改數(shù)據(jù)類型是一致的。
-
只有創(chuàng)建數(shù)組后才能給數(shù)組元素賦值??梢允褂胣ew操作符創(chuàng)建數(shù)組,語法如下:newelementType[array.Size] (數(shù)據(jù)類型[數(shù)組大小])。
-
數(shù)組中的每個元素都是使用語法arravRefVarlindex1 (數(shù)組引用變量[下標(biāo)])表示的。下標(biāo)必須是一個整數(shù)或一個整數(shù)表達(dá)式。
-
創(chuàng)建數(shù)組之后,它的大小就不能改變,使用array.length就可以得到數(shù)組的大小。由于數(shù)組的下標(biāo)總是從0開始,所以,最后一個下標(biāo)總是array.length-1。如果試圖引用數(shù)組界外的元素,就會發(fā)生越界錯誤。千萬不要用下標(biāo)1訪問數(shù)組的第一個元素,其實際上對于該元素的下標(biāo)應(yīng)該是0。這個錯誤稱為下標(biāo)過1錯誤(index off-by-one error)。
-
Java有一個稱為數(shù)組初始化語法 (array initializer)的表達(dá)式,它將數(shù)組的聲明、創(chuàng)建和初始化合并為一條語句,其語法為:
元素類型[] 數(shù)組引用變量={value0,value1,.·,valuek}
-
將數(shù)組參數(shù)傳遞給方法時,實際上傳遞的是數(shù)組的引用,更準(zhǔn)確地說,被調(diào)用的方法可以修改調(diào)用者的原始數(shù)組的元素。
貳._.二維數(shù)組
Java使用大端字節(jié)序的優(yōu)勢在于它可以更容易地在不同系統(tǒng)之間進(jìn)行互操作。這是因為大端字節(jié)序是網(wǎng)絡(luò)協(xié)議和文件格式中最廣泛使用的字節(jié)序。[進(jìn)行通信和交換數(shù)據(jù)。]
二維數(shù)組是Java中的一種數(shù)據(jù)結(jié)構(gòu),它可以被看作是一個由多個一維數(shù)組組成的數(shù)組。
每個一維數(shù)組都代表著一個行,而這些一維數(shù)組的長度可以不同。 [用于存儲表格數(shù)據(jù),例如矩陣、棋盤等等。]
?
1>Java二維數(shù)組創(chuàng)建
Java中創(chuàng)建二維數(shù)組,可以使用以下語法:
//Length1 和 Length2 是整數(shù) 【左行右列】
type[][] typeName = new type[Length1][Length2];
//擁有以下3種格式
type[][] arrayName = new type[][]{值 1,值 2,值 3,…,值 n}; // 在定義時初始化
type[][] arrayName = new type[Length1][Length2]; // 給定空間,在賦值
type[][] arrayName = new type[Length1][]; // 數(shù)組第二維長度為空,可變化
創(chuàng)建形式
int[][] arrayName = new int[rows][columns];
//創(chuàng)建一個具有3行和4列的二維數(shù)組
int[][] arrayName = new int[3][4];
數(shù)組名 = new 數(shù)據(jù)類型[第1維的長度][];
//單獨初始化每一行來創(chuàng)建二維數(shù)組
int[][] arrayName = new int[3][];
arrayName[0] = new int[4];
arrayName[1] = new int[5];
arrayName[2] = new int[6];
要初始化一個二維數(shù)組,可以先創(chuàng)建一個具有所需行數(shù)的數(shù)組,然后為每一行分配空間,方法是將一個具有所需列數(shù)的新數(shù)組分配給每一行。
多維數(shù)組的動態(tài)初始化(以二維數(shù)組為例)
直接為每一維分配空間,格式如下:type 可以為基本數(shù)據(jù)類型和復(fù)合數(shù)據(jù)類型,typeLength1 和 typeLength2 必須為正整數(shù),typeLength1 為行數(shù),typeLength2 為列數(shù)。
int[][] a = new int[2][3];
二維數(shù)組 a 可以看成一個兩行三列的數(shù)組。
- 從最高維開始,分別為每一維分配空間,例如:
String[][] s = new String[2][];
s[0] = new String[2];
s[1] = new String[3];
s[0][0] = new String("Good");
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");
type[][] typeName = new type[typeLength1][typeLength2];
2>Java數(shù)組-- >為每一維分配空間
??
從高維開始進(jìn)行數(shù)組初始化的例子:
a = new int[3][]; // 先為第一維分配空間,注意這時沒有為第二維分配空間
a[0] = new int[2]; // 然后為第二維的每一個元素(數(shù)組)分配空間
a[1] = new int[1];
a[2] = new int[3];
Java二維數(shù)組實現(xiàn)算法
對于矩陣運算,存儲矩陣的值,執(zhí)行加法、減法和乘法等操作。
對于圖像處理,表示圖像的像素,并對圖像應(yīng)用濾鏡或變換。
對于圖算法,表示圖的鄰接矩陣,并執(zhí)行查找兩個節(jié)點之間的最短路徑等操作
矩陣運算–>乘法
int[][] matrix1 = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
int[][] matrix2 = {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}};
int[][] result = new int[2][2];
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 5; k++) {
result[i][j] += matrix1[i][k] * matrix2[k][j];
}
}
}
// 打印結(jié)果
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
System.out.print(result[i][j] + " ");
}
System.out.println();
}
九九乘法表:
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
table[i][j] = (i + 1) * (j + 1);
}
}
for (int i = 0; i < 9; i++) {
for (int j = i; j < 9; j++) {
System.out.print((i+1) + "*" + (j+1) + "=" + table[i][j] + "\t");
}
System.out.println();
}
叁._.不規(guī)則數(shù)組
在 Java 中,不規(guī)則數(shù)組也被稱為“不規(guī)則多維數(shù)組”或“交錯數(shù)組”,它是指嵌套的一維數(shù)組長度不一致的數(shù)組結(jié)構(gòu)。
聲明一個不規(guī)則數(shù)組的方式和聲明一個普通的多維數(shù)組類似,只不過需要在聲明時指定每個一維數(shù)組的長度。例如,聲明一個二維不規(guī)則數(shù)組:
int[][] arr = new int[3][];
arr[0] = new int[]{1, 2, 3};
arr[1] = new int[]{4, 5};
arr[2] = new int[]{6, 7, 8, 9};
上面的代碼創(chuàng)建了一個二維不規(guī)則數(shù)組 arr,其中第一維長度為 3,第二維長度不一致。第一個一維數(shù)組包含 3 個元素,第二個一維數(shù)組包含 2 個元素,第三個一維數(shù)組包含 4 個元素。
我們也可以使用如下方式創(chuàng)建一個不規(guī)則數(shù)組:
int[][] arr = {{1, 2, 3}, {4, 5}, {6, 7, 8, 9}};
使用循環(huán)語句訪問不規(guī)則數(shù)組可以使用維度不同的嵌套循環(huán),例如:
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
上面的代碼會輸出以下結(jié)果:
1 2 3
4 5
6 7 8 9
注意事項
在使用不規(guī)則數(shù)組時,需要注意以下幾點:
- 不規(guī)則數(shù)組中的每個一維數(shù)組的長度可以不同,但是每個一維數(shù)組本身必須是一個合法的數(shù)組對象,否則會拋出 NullPointerException 異常。
- 創(chuàng)建不規(guī)則數(shù)組時,必須先創(chuàng)建第一維的數(shù)組,然后再依次為每個一維數(shù)組分配內(nèi)存空間。
- 訪問不規(guī)則數(shù)組的元素時,需要使用嵌套循環(huán)語句。由于每個一維數(shù)組的長度不同,因此需要使用 arr[i].length 來獲取第 i 個一維數(shù)組的長度。
- 不規(guī)則數(shù)組的長度不可變,一旦創(chuàng)建后,不能改變數(shù)組的大小。如果需要增加或刪除元素,需要創(chuàng)建一個新的數(shù)組,將舊數(shù)組中的元素拷貝到新數(shù)組中。
- 不規(guī)則數(shù)組的性能可能會比規(guī)則數(shù)組差,因為不規(guī)則數(shù)組需要使用多個一維數(shù)組來實現(xiàn),而且由于每個一維數(shù)組的長度不同,可能會導(dǎo)致內(nèi)存碎片化的問題。因此,在實際應(yīng)用中,應(yīng)該根據(jù)具體情況選擇合適的數(shù)據(jù)結(jié)構(gòu)來存儲數(shù)據(jù)。
肆._.其他知識點
棧----方法運行時使用的內(nèi)存,比如main方法運行,進(jìn)入方法棧中執(zhí)行
堆----存儲對象或者數(shù)組,new來創(chuàng)建的,都存儲在堆內(nèi)存
方法區(qū)----存儲可以運行的class文件
本地方法棧----JVM在使用操作系統(tǒng)功能的時候使用,和我們開發(fā)無關(guān)
寄存器----CPU使用,和我們開發(fā)無關(guān)
1>棧
方法運行時使用的內(nèi)存比如main方法運行,進(jìn)入方法棧中執(zhí)行。開始執(zhí)行時會進(jìn)棧代碼執(zhí)行完畢會出棧
.存取速度比堆要快,棧中的數(shù)據(jù)大小與生存期必須是確定的,棧數(shù)據(jù)可以共享。
棧的內(nèi)存要遠(yuǎn)遠(yuǎn)小于堆內(nèi)存,少用遞歸
棧:主要用于存儲局部變量和對象的引用變量,每個線程都會有一個獨立的??臻g,所以線程之間是不共享數(shù)據(jù)的。
Java確實會在棧中為變量分配內(nèi)存空間。當(dāng)變量超出其作用域時,Java會自動釋放為該變量分配的內(nèi)存空間,以便該空間可以立即被另作他用。棧內(nèi)存歸屬于單個線程,每個線程都會有一個棧內(nèi)存,其存儲的變量只能在其所屬線程中可見,即棧內(nèi)存可以理解成線程的私有內(nèi)存。但是,對于在堆內(nèi)存中分配的對象,情況有所不同。堆內(nèi)存中的對象對所有線程可見,因為它們不屬于任何特定線程。
2>堆
new來創(chuàng)建的,都存儲在堆內(nèi)存new 出來的東西會在這塊內(nèi)存中開辟空間并產(chǎn)生地址
堆:主要用于存儲實例化的對象,數(shù)組。由JVM動態(tài)分配內(nèi)存空間【基本類型的變量和對象的引用變量都在函數(shù)的棧內(nèi)存中分配。】。一個JVM只有一個堆內(nèi)存,線程是可以共享數(shù)據(jù)的。
堆內(nèi)存中的對象對所有線程可見。這意味著堆內(nèi)存中的對象可以被所有線程訪問。這是Java中多線程編程的一個重要方面,因為它允許多個線程同時訪問和操作相同的對象。
1.只要是new出來的一定是在堆里面開辟了一個小空間
2.如果new了多次,那么在堆里面有多個小空間,每個小空間中都有各自的數(shù)據(jù)
3>通過CursorCode再次理解
4>當(dāng)兩個數(shù)組指向同一個小空間時,其中一個數(shù)組對小空間中的值發(fā)生了改變,那么其他數(shù)組再次訪問的時候都是修改之后的結(jié)果了
public static void main(String[] args) {
int[] arr1 = (1, 22);
int[] arr2 = arr1;
System.out.println(arr1[0]);
System.out.println(arr2[0]);
arr2[0]=0;
System.out.println(arr1[0]);
System.out.println(arr2[0]);
}
圖片來源于網(wǎng)絡(luò)
-
引用數(shù)據(jù)類型是指在Java中,變量存儲的是對象的引用而不是對象本身。這意味著變量指向內(nèi)存中的對象,而不是包含對象本身的值。這與基本數(shù)據(jù)類型不同,基本數(shù)據(jù)類型的變量包含它們自己的值。
包括類、接口、數(shù)組和枚舉類型。當(dāng)你創(chuàng)建一個對象時,實際上是在堆上分配了一塊內(nèi)存來存儲該對象,并返回一個引用,該引用指向該對象的內(nèi)存地址。你可以將該引用存儲在變量中,并使用該變量來訪問該對象。// 聲明一個類類型的變量 MyClass obj;· ·// 創(chuàng)建一個對象并將其分配給變量 obj = new MyClass();· ·// 訪問對象的屬性和方法 obj.myMethod();
??文章來源:http://www.zghlxwxcb.cn/news/detail-476130.html -
這是因為數(shù)組的長度是固定的,而數(shù)組的索引是從0開始的,所以最后一個元素的索引就是數(shù)組長度減1.因此,以數(shù)組的長度-1作為數(shù)組的結(jié)束索引是為了保證不會訪問到數(shù)組之外的內(nèi)存空間,從而保證程序的安全性。 ??文章來源地址http://www.zghlxwxcb.cn/news/detail-476130.html
到了這里,關(guān)于我在VScode學(xué)Java(Java一維數(shù)組、二維數(shù)組、JVM中的堆和棧)重制版的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!