goto 語法在 PHP 中的使用
Java陣列
目錄
- Java陣列
- ArrayTest01——陣列的一些概念
- ArrayTest02——如何選擇陣列的初始化方式
- ArrayTest03——當一個方法上,引數的型別是一個數組的時候
- ArrayTest04——當一個方法的引數是一個數組的時候,我們還可以採用這種方式傳
- ArrayTest05——main方法上面的“String[] args”有什麼用?
- ArrayTest06——模擬一個系統,假設這個系統要使用,必須輸入使用者名稱和密碼
- ArrayTest07——深入理解陣列中儲存的型別為引用資料型別
- ArrayTest08——一維陣列的擴容
- ArrayTest09——java中的二維陣列
- ArrayTest10——二維陣列中元素的讀和改
- ArrayTest11——二維陣列的遍歷
- ArrayTest12——動態初始化二維陣列
ArrayTest01——陣列的一些概念
-
什麼是陣列?
字面意思是“一組資料”。
陣列實際上是一個容器,可以同時容納多個元素。(陣列是多個數據的集合。)
Java語言中的陣列是一種引用資料型別。不屬於基本資料型別。陣列的父類是Object。
-
陣列儲存什麼樣的資料?
陣列當中可以儲存“基本資料型別”的資料,也可以儲存“引用資料型別”的資料。
java中的陣列要求陣列中元素的型別統一。比如int型別陣列只能儲存int型別,Person型別陣列只能儲存Person型別。
例如:超市購物,購物袋中只能裝蘋果,不能同時裝蘋果和橘子。(陣列中儲存的元素型別統一) -
陣列儲存在哪個地方?
陣列因為是引用型別,所以陣列物件是堆記憶體當中。(陣列是儲存在堆當中的)
陣列當中如果儲存的是“java物件”的話,實際上儲存的是物件的“引用(記憶體地址)”,陣列中不能直接儲存java物件。
-
陣列有哪些特點?
陣列一旦建立,在java中規定,長度不可變。(陣列長度不可變)
陣列在記憶體方面儲存的時候,陣列中的元素記憶體地址(儲存的每一個元素都是有規則的挨著排列的)是連續的。記憶體地址連續。
陣列中首元素的記憶體地址作為整個陣列物件的記憶體地址。
陣列中每一個元素都是有下標的,下標從0開始,以1遞增。最後一個元素的下標是:length - 1,下標非常重要,因為我們對陣列中元素進行“存取”的時候,都需要通過下標來進行。
-
陣列的分類?
陣列的分類:一維陣列、二維陣列、三維陣列、多維陣列...(一維陣列較多,二維陣列偶爾使用!)
-
如何獲得陣列的長度?
所有的陣列物件都有length屬性(java自帶的),用來獲取陣列中元素的個數。
-
陣列這種資料結構的優點是什麼?
優點:查詢/查詢/檢索某個下標上的元素時效率極高。可以說是查詢效率最高的一個數據結構。
為什麼檢索效率高?
第一:每一個元素的記憶體地址在空間儲存上是連續的。
第二:每一個元素型別相同,所以佔用空間大小一樣。
第三:知道第一個元素記憶體地址,知道每一個元素佔用空間的大小,又知道下標,所以
通過一個數學表示式就可以計算出某個下標上元素的記憶體地址。直接通過記憶體地址定位
元素,所以陣列的檢索效率是最高的。 陣列中儲存100個元素,或者儲存100萬個元素,在元素查詢/檢索方面,效率是相同的,
因為陣列中元素查詢的時候不會一個一個找,是通過數學表示式計算出來的。(算出一個
記憶體地址,直接定位的。) -
陣列這種資料結構的缺點是什麼?
第一:由於為了保證陣列中每個元素的記憶體地址連續,所以在陣列上隨機刪除或者增加元素的時候,效率較低,因為隨機增刪元素會涉及到後面元素統一向前或者向後位移的操作。
第二:陣列不能儲存大資料量,為什麼?
因為很難在記憶體空間上找到一塊特別大的連續的記憶體空間。注意:對於陣列中最後一個元素的增刪,是沒有效率影響的。
-
怎麼宣告/定義一個一維陣列?
int[] array1;
double[] array2;
boolean[] array3;
String[] array4;
Object[] array5; -
怎麼初始化一個一維陣列呢?
包括兩種方式:靜態初始化一維陣列,動態初始化一維陣列。
靜態初始化語法格式:int[] array = {100, 2100, 300, 55};
動態初始化語法格式:int[] array = new int[5]; // 初始化一個5個長度的int型別陣列,每個元素預設值0
String[] names = new String[6]; // 初始化6個長度的String型別陣列,每個元素預設值null。
public class ArrayTest01 {
public static void main(String[] args) {
// 宣告一個int型別的陣列,使用靜態初始化的方式
int[] a = {1, 100, 10, 20, 55, 689};
// 這是C++風格,不建議java中使用。
//int a[] = {1, 100, 10, 20, 55, 689};
// 所有的陣列物件都有length屬性
System.out.println("陣列中元素的個數" + a.length);
// 陣列中每一個元素都有下標
// 通過下標對陣列中的元素進行存和取。
// 取(讀)
System.out.println("第一個元素 = " + a[0]);
System.out.println("最後一個元素 = " + a[5]);
System.out.println("最後一個元素 = " + a[a.length - 1]);
// 存(改)
// 把第一個元素修改為111
a[0] = 111;
// 把最後一個元素修改為0
a[a.length - 1] = 0;
System.out.println("第一個元素 = " + a[0]);
System.out.println("最後一個元素 = " + a[5]);
// 一維陣列怎麼遍歷呢?
for(int i = 0; i < a.length; i++){
System.out.println(a[i]); // i是從0到5,是下標
}
// 下標為6表示第7個元素,第7個元素沒有,下標越界了。會出現什麼異常呢?
//System.out.println(a[6]); //ArrayIndexOutOfBoundsException(比較著名的異常。)
// 從最後一個元素遍歷到第1個元素
for (int i = a.length - 1; i >= 0; i--) {
System.out.println("顛倒順序輸出-->" + a[i]);
}
}
}
ArrayTest02——如何選擇陣列的初始化方式
-
Java每個型別的預設值?
資料型別 預設值
byte 0
short 0
int 0
long 0L
float 0.0F
double 0.0
boolean false
char \u0000
引用資料型別 null -
什麼時候採用靜態初始化方式,什麼時候使用動態初始化方式呢?
當你建立陣列的時候,確定陣列中儲存哪些具體的元素時,採用靜態初始化方式。
當你建立陣列的時候,不確定將來陣列中儲存哪些資料,你可以採用動態初始化的方式,預先分配記憶體空間。
public class ArrayTest02 {
public static void main(String[] args) {
// 宣告/定義一個數組,採用動態初始化的方式建立
int[] a = new int[4]; // 建立長度為4的int陣列,陣列中每個元素的預設值是0
// 後期賦值
a[0] = 1;
a[1] = 100;
a[2] = 111;
a[3] = 222; // 注意下標別越界。
// 初始化一個Object型別的陣列,採用動態初始化方式
Object[] objs = new Object[3]; // 3個長度,動態初始化,所以每個元素預設值是null
String[] strs = new String[3];
// 採用靜態初始化的方式
String[] strs2 = {"abc", "def", "xyz"};
// 儲存Object,採用靜態初始化呢?
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
Object[] objects = {o1, o2, o3};
Object[] objects = {new Object(), new Object(), new Object()};
}
}
ArrayTest03——當一個方法上,引數的型別是一個數組的時候
有兩個方法如下:
public static void printArray(int[] array){
for(int i = 0; i < array.length; i++){
System.out.println(array[i]);
}
}
public static void printArray(String[] args){
for(int i = 0; i < args.length; i++){
System.out.println("String陣列中的元素:" + args[i]);
}
}
引數的型別是一個數組的時候,該如何傳入引數?
方式1:
//int型陣列
int[] x = {1,2,3,4};
printArray(x);
//String型別陣列
String[] stringArray = {"abc", "def", "hehe", "haha"};
printArray(stringArray);
方式2:
printArray(new String[3]); //3個null
priantArray(new int[4]); //4個0
ArrayTest04——當一個方法的引數是一個數組的時候,我們還可以採用這種方式傳
引數為陣列的方法如下:
// 在為什麼要使用靜態方法?因為不需要new物件就可以呼叫該方法。
public static void printArray(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
傳引數:
printArray(new int[]{1,2,3});
ArrayTest05——main方法上面的“String[] args”有什麼用?
-
首先誰負責呼叫main方法?
JVM。
-
main方法上面的“String[] args”有什麼用?
JVM呼叫main方法的時候,會自動傳一個String陣列過來。
JVM預設傳遞過來的這個陣列物件的長度?預設是0。
-
這個陣列什麼時候裡面會有值呢?
其實這個陣列是留給使用者的,使用者可以在控制檯上輸入引數,這個引數自動會被轉換為“String[] args”.
例如這樣執行程式:java ArrayTest05 abc def xyz
那麼這個時候JVM會自動將“abc def xyz”通過空格的方式進行分離,分離完成之後,自動放到“String[] args”陣列當中。
所以main方法上面的String[] args陣列主要是用來接收使用者輸入引數的。
把abc def xyz 轉換成字串陣列:{"abc","def","xyz"}
public class ArrayTest05 {
// 這個方法程式設計師負責寫出來,JVM負責呼叫。JVM呼叫的時候一定會傳一個String陣列過來。
public static void main(String[] args) {
// JVM預設傳遞過來的這個陣列物件的長度?預設0
// 通過測試得出:args不是null。
System.out.println("JVM給傳遞過來的String陣列引數,它這個陣列的長度是?" + args.length);
// 以下這一行程式碼表示的含義:陣列物件建立了,但是陣列中沒有任何資料。
//String[] strs = new String[0];
//String[] strs = {}; // 靜態初始化陣列,裡面沒東西。
//printLength(strs);
}
public static void printLength(String[] args){
System.out.println(args.length); // 0
}
}
ArrayTest06——模擬一個系統,假設這個系統要使用,必須輸入使用者名稱和密碼
package com.bjpowernode.javase.array;
/*
模擬一個系統,假設這個系統要使用,必須輸入使用者名稱和密碼。
*/
public class ArrayTest06 {
// 使用者名稱和密碼輸入到String[] args陣列當中。
public static void main(String[] args) {
if(args.length != 2){
System.out.println("使用該系統時請輸入程式引數,引數中包括使用者名稱和密碼資訊,例如:zhangsan 123");
return;
}
// 程式執行到此處說明使用者確實提供了使用者名稱和密碼。
// 接下來你應該判斷使用者名稱和密碼是否正確。
// 取出使用者名稱
String username = args[0];
// 取出密碼
String password = args[1];
// 假設使用者名稱是admin,密碼是123的時候表示登入成功。其它一律失敗。
// 判斷兩個字串是否相等,需要使用equals方法。
//if(username.equals("admin") && password.equals("123")){
// 這樣編寫是不是可以避免空指標異常。
// 採用以下編碼風格,及時username和password都是null,也不會出現空指標異常。(這是老程式設計師給的一條程式設計經驗。)
if("admin".equals(username) && "123".equals(password)){
System.out.println("登入成功,歡迎[" + username + "]回來");
System.out.println("您可以繼續使用該系統....");
}else{
System.out.println("驗證失敗,使用者名稱不存在或者密碼錯誤!");
}
}
}
ArrayTest07——深入理解陣列中儲存的型別為引用資料型別
一維陣列的深入,陣列中儲存的型別為:引用資料型別。
對於陣列來說,實際上只能儲存java物件的“記憶體地址”。陣列中儲存的每個元素是“引用”。
public class ArrayTest07 {
public static void main(String[] args) {
// 建立一個Animal型別的陣列
Animal a1 = new Animal();
Animal a2 = new Animal();
Animal[] animals = {a1, a2};
// 對Animal陣列進行遍歷
for (int i = 0; i < animals.length; i++) {
animals[i].move(); // 這個move()方法不是陣列的。是陣列當中Animal物件的move()方法。
}
// 動態初始化一個長度為2的Animal型別陣列。
Animal[] ans = new Animal[2];
// 建立一個Animal物件,放到陣列的第一個位置。
ans[0] = new Animal();
// Animal陣列中可以存放Cat型別的資料,因為Cat是一個Animal。
// Cat是Animal的子類。
ans[1] = new Cat();
// 建立一個Animal型別的陣列,陣列當中儲存Cat和Bird
Cat c = new Cat();
Bird b = new Bird();
Animal[] anis = {c, b};
//Animal[] anis = {new Cat(), new Bird()}; // 該陣列中儲存了兩個物件的記憶體地址。
for (int i = 0; i < anis.length; i++){
// 這個取出來的可能是Cat,也可能是Bird,不過肯定是一個Animal
// 如果呼叫的方法是父類中存在的方法不需要向下轉型。直接使用父型別引用呼叫即可。
// 呼叫子物件特有方法的話,需要向下轉型!!!
if(anis[i] instanceof Cat){
Cat cat = (Cat)anis[i];
cat.catchMouse();
}else if(anis[i] instanceof Bird){
Bird bird = (Bird)anis[i];
bird.sing();
}
}
}
}
class Animal{
public void move(){
System.out.println("Animal move...");
}
}
// 商品類
class Product{
}
// Cat是子類
class Cat extends Animal {
public void move(){
System.out.println("貓在走貓步!");
}
// 特有方法
public void catchMouse(){
System.out.println("貓抓老鼠!");
}
}
// Bird子類
class Bird extends Animal {
public void move(){
System.out.println("Bird Fly!!!");
}
// 特有的方法
public void sing(){
System.out.println("鳥兒在歌唱!!!");
}
}
ArrayTest08——一維陣列的擴容
在java開發中,陣列長度一旦確定不可變,那麼陣列滿了怎麼辦?
java中對陣列的擴容是:
先新建一個大容量的陣列,然後將小容量陣列中的資料一個一個拷貝到大陣列當中。
結論:陣列擴容效率較低。因為涉及到拷貝的問題。所以在以後的開發中請注意:儘可能少的進行陣列的拷貝。
可以在建立陣列物件的時候預估計以下多長合適,最好預估準確,這樣可以減少陣列的擴容次數。提高效率。
java中的陣列是怎麼進行拷貝的呢?
//System類的靜態方法
static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
//引數
src - 源陣列。
srcPos - 源陣列中的起始位置。
dest - 目標陣列。
destPos - 目標資料中的起始位置。
length - 要複製的陣列元素的數量。
示例:
public class ArrayTest08 {
public static void main(String[] args) {
// 拷貝源(從這個陣列中拷貝)
int[] src = {1, 11, 22, 3, 4};
// 拷貝目標(拷貝到這個目標陣列上)
int[] dest = new int[20]; // 動態初始化一個長度為20的陣列,每一個元素預設值0
System.arraycopy(src, 0, dest, 0, src.length);
// 陣列中如果儲存的元素是引用,可以拷貝嗎?當然可以。
String[] strs = {"hello", "world!", "study", "java", "oracle", "mysql", "jdbc"};
String[] newStrs = new String[20];
System.arraycopy(strs, 0, newStrs, 0, strs.length);
System.out.println("================================");
Object[] objs = {new Object(), new Object(), new Object()};
Object[] newObjs = new Object[5];
// 思考一下:這裡拷貝的時候是拷貝物件,還是拷貝物件的地址。(地址。)
System.arraycopy(objs, 0, newObjs, 0, objs.length);
for (int i = 0; i < newObjs.length; i++) {
System.out.println(newObjs[i]);
}
}
}
ArrayTest09——java中的二維陣列
-
怎麼理解二維陣列?
二維陣列其實是一個特殊的一維陣列,特殊在這個一維陣列當中的每一個元素是一個一維陣列。
-
三維陣列是什麼?
三維陣列是一個特殊的二維陣列,特殊在這個二維陣列中每一個元素是一個一維陣列。
際的開發中使用最多的就是一維陣列。二維陣列也很少使用。三維陣列幾乎不用。
-
二維陣列靜態初始化
int[][] array = {{1,1,1},{2,3,4,5},{0,0,0,0},{2,3,4,5},{2,3,4,5},{2,3,4,5},{2,3,4,5}};
示例:
public class ArrayTest09 {
public static void main(String[] args) {
// 一維陣列
int[] array = {100, 200, 300};
System.out.println(array.length); // 3
System.out.println("=======================");
// 二維陣列
// 以下程式碼當中:裡面的是4個一維陣列。
int[][] a = {
{100, 200, 300},
{30, 20, 40, 50, 60},
{6, 7, 9, 1},
{0}
};
System.out.println(a.length); // 4
System.out.println(a[0].length); // 3
System.out.println(a[1].length); // 5
System.out.println(a[2].length); // 4
System.out.println(a[3].length); // 1
// 裡面的是5個一維陣列。
int[][] a2 = {
{100, 200, 300},
{30, 20, 40, 50, 60},
{6, 7, 9, 1},
{0},
{1,2,3,4,5}
};
}
}
ArrayTest10——二維陣列中元素的讀和改
-
如何表示二維陣列中的一個一維陣列中的元素?
a[二維陣列中的一維陣列的下標][一維陣列的下標]
例如:
a[0][0]:表示第1個一維陣列中的第1個元素。
a[3][100]:表示第4個一維陣列中的第101個元素。
示例:
public class ArrayTest10 {
public static void main(String[] args) {
// 二維陣列
int[][] a = {
{34,4,65},
{100,200,3900,111},
{0}
};
// 請取出以上的第1個一維陣列。
int[] 我是第1個一維陣列 = a[0];
int 我是第1個一維陣列中的第1個元素 = 我是第1個一維陣列[0];
// 以下程式碼的由來是因為以上程式碼的合併導致的。
System.out.println(a[0][0]);
// 取出第2個一維陣列當中第3個元素
System.out.println("第二個一維陣列中第三個元素:" + a[1][2]);
// 取出第3個一維陣列當中第1個元素
System.out.println("第3個一維陣列中第1個元素:" + a[2][0]);
// 改
a[2][0] = 11111;
System.out.println(a[2][0]);
// 注意別越界。
//java.lang.ArrayIndexOutOfBoundsException
//System.out.println(a[2][1]);
}
}
ArrayTest11——二維陣列的遍歷
public class ArrayTest11 {
public static void main(String[] args) {
// 二維陣列
String[][] array = {
{"java", "oracle", "c++", "python", "c#"},
{"張三", "李四", "王五"},
{"lucy", "jack", "rose"}
};
//遍歷二維陣列
for(int i = 0; i < array.length; i++){ // 外層迴圈3次。(負責縱向。)
for(int j = 0; j < array[i].length; j++){
System.out.print(array[i][j] + " ");
}
System.out.println();
}
}
}
ArrayTest12——動態初始化二維陣列
public class ArrayTest12 {
public static void main(String[] args) {
// 3行4列。
// 3個一維陣列,每一個一維陣列當中4個元素。
int[][] array = new int[3][4];
// 靜態初始化
int[][] a = {{1,2,3,4},{4,5,6,76},{1,23,4}};
printArray(a);
// 沒有這種語法
//printArray({{1,2,3,4},{4,5,6,76},{1,23,4}});
// 可以這樣寫。
printArray(new int[][]{{1,2,3,4},{4,5,6,76},{1,23,4}});
}
public static void printArray(int[][] array){
// 遍歷二維陣列。
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();
}
}
}