Java 25天基礎-DAY 04
Java 25天基礎-DAY 04
1、數組定義:
數組:同一種數據類型的集合,其實數組就是個容器
數組的好處:可以自動給數組中的元素從0開始編號,方便操作這些元素
格式1:
元素類型[] 數組名 = new 元素類型 [元素個數或數組長度];
示例: int [] arr = new int [5];
格式2:
元素類型[] 數組名 = new 元素類型 [元素, 元素, ...];
示例:int [] arr = new int []{2,4,6,8};
int [] arr = {2,4,6,8}
java在啟動時一共在內存中劃分了5片空間:
1、棧內存 :用於存儲局部變量,當數據使用完,所占空間會自動釋放
2、堆內存 :數組和對象,通過new建立的實例都存放在堆內存中
每一個實體都有內存地址值
實體中的變量都有默認初始化值
實體在不被使用,會在不確定的時間內被垃圾回收器回收。
下麵三種暫時不用 3、方法區;4、本地方法區;5、寄存器
例1:數組的書寫方式以及不同數據類型的默認輸出等
class shuzu1
{
public static void main(String[] args)
{
int [] arr = new int []{1,2,3,45,6,6};//正規方式
System.out.println(arr[3]);
int [] ar = {12,3,4,2,55};//簡寫方式
System.out.println(ar[3]);
int [] a = new int [4]; // 數組隻要被定義就存在值 (0)
System.out.println("int="+a[3]); //無數值定義默認輸出為0
double [] b = new double [5];
System.out.println("double="+b[3]); //無數值定義默認輸出為0.0
float [] c = new float [5];
System.out.println("float="+c[3]); //無數值定義默認輸出為0.0f(但是編譯後輸出為0.0)
boolean [] d = new boolean [5];
System.out.println("boolean="+d[3]);//無數值定義默認輸出為false
System.out.println("=========================================");
//檢查下麵是否有垃圾存在?
int [] x=new int []{1,2,3,21,4,6,5,4};
int [] y=x; // 將y也指向數組
//當y重新定義數組後 int [] y=new int []{1,3,4,11,42}; x =null; 這是x對應的數組為垃圾。
x =null;
System.out.println(y[3]);
//從上麵實驗得知,數組並沒有被當作垃圾回收,因為數組y仍然在使用。
System.out.println("=========================================");
//從下麵實驗得知,隻要new後就會在堆內存中創建一個新的數組。
int [] z=new int []{1,2,3,21,4,6,5,4};
int [] z1=new int []{12,23,32,221,24,36,35,14};
System.out.println(z[3]);
System.out.println(z1[3]);
System.out.println("=========================================");
//數組中常見問題
int [] zz= new int [3];
//System.out.println(zz[3]);
/*
編譯不報錯,運行時報以下錯誤:數組異常,
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at shuzu1.main(shuzu1.java:52)
操作數組時,訪問到了數組中不存在的角標。
*/
System.out.println("=========================================");
int [] zzz= new int [3];
zzz=null;
System.out.println(zzz[1]);
/*
編譯不報錯,運行時報以下錯誤:空指針異常
Exception in thread "main" java.lang.NullPointerException
at shuzu1.main(shuzu1.java:62)
當引用沒有任何指針指向值為null的情況,該引用還在用於操作實體。
*/
}
}
2、數組的遍曆:
獲取數組中的元素,通常會用到遍曆(循環)。
例1:遍曆時,使用數組的方式:數組名稱.length
class shuzu2
{
public static void main(String[] args)
{
int [] arr = new int [] {1,4,6,9,10};
for (int x=0;x<arr.length ;x++ )
{
System.out.println(arr[x]);
}
System.out.println("You are hero");
}
}
輸出結果:
D:\Skill\JAVA\2017>java shuzu2
1
4
6
9
10
You are hero
例2、優化輸出方式:
class shuzu2
{
public static void main(String[] args)
{
int [] arr = new int [] {1,4,6,9,10};
for (int x=0;x<arr.length ;x++ )
{
//數組中有一個屬性可以直接得到元素的個數,length
//System.out.print("arr["+x+"]="+arr[x]+", ");
System.out.print("arr["+x+"]="+arr[x]+", ");
}
System.out.println();
}
}
輸出結果:
D:\Skill\JAVA\2017>java shuzu2
arr[0]=1, arr[1]=4, arr[2]=6, arr[3]=9, arr[4]=10,
D:\Skill\JAVA\2017>
3、數組中的元素求和
例:
class shuzu2
{
public static void main(String[] args)
{
int [] arr = new int [] {1,4,6,9,10};
int sum=0; //定義一個變量用來記住循環內部加法的和。
for (int x=0;x<arr.length ;x++ )
{
sum=arr[x]+sum; //可以簡寫為:sum+=arr[x],將數組內所有元素相加。
}
System.out.println("sum="+sum);
System.out.println("我真牛逼!!!!");
}
}
4、使用函數定義功能
例:定義一個功能,用於打印數組中的元素,元素間用,號隔開。使用函數的方式實現。
class shuzu2
{
public static void main(String[] args)
{
int [] arr = new int [] {1,4,6,9,10};
suzu (arr);
System.out.println("我真牛逼!!!!");
}
public static void suzu (int []a)
{
for (int x=0;x<a.length ;x++ )
{
if (x!=a.length-1) //使用if語句排除掉最後一個逗號,如果x不等於最後一個元素的角標值則打印的帶逗號,否則直接打印元素並回車。
System.out.print("arr="+a[x]+",");
else
System.out.println("arr="+a[x]);
}
}
}
5、獲取數組中值最大的元素:
給定一個數組{1,2,4,6,9,3};
1、獲取數組中的最大值
分析思路:
1、互相比較,每一次比較都有一個較大的值,因為該值不確定,通過一個變量來存儲。
2、讓數組中的每一個元素都和這個變量中的值進行比較。如果大於了變量中的值,就用該變量記錄較大的值。
3、當所有的元素都比較完成,那麼該變量中存儲的就是數組中的最大值了。
步驟:
1,定義變量,初始化為數組中的任意一個元素即可。
2、通過循環語句對數組進行遍曆
3、在遍曆過程中定義判斷條件,如果遍曆到的元素比變量中的元素大,就賦值給該變量。
需要定義一個功能來完成,以提高複用性。
1、明確結果,數組中的最大元素int
2、未知內容:一個數組 int []
例:記錄元素的方式
class shuzu2
{
public static void main(String[] args)
{
int [] arr = new int [] {1,4,60,9,10};
suzu (arr);
System.out.println("我真牛逼!!!!");
}
public static void suzu (int a[])
{
int max= a [0]; //定義一個變量來存儲最大元素
for (int x=0;x<a.length ;x++ )
{
if (max < a [x]) //判斷max是否小於a[x]
{
max = a [x]; //如果max小於a[x]則將值付給max,記錄了最大的元素。
}
}
System.out.println("MAX="+max);
}
}
例2、記錄角標的方式
class shuzu2
{
public static void main(String[] args)
{
int [] arr = new int [] {1,4,60,9,10};
int Max=suzu (arr); //調用函數suzu並傳入arr數組,然後將返回值付給Max。
System.out.println("MAX="+Max);
System.out.println("我真牛逼!!!!");
}
public static int suzu (int a[])
{
int max=0; //定義一個max變量並賦值為0,該值為下麵a數組的0角標。
for (int x=1;x<a.length ;x++ )
{
if (a [max] < a [x]) //第一次循環時,用該數組的0角標上的元素和1角標上的元素進行比較。後麵循環以此類推。
{
max =x; //記住最大值得角標。
}
}
return a[max]; //返回最大值的角標
}
}
6、選擇排序:
思路:遍曆、條件語句、第三方變量。
數組角標1循環向後比較,每次都少一個比較值,相當下圖
****
***
**
*
也就是大圈套小圈的for嵌套循環。
如果想打印出排序後的結果。
可以使用數組
特點:內循環結束一次,最值出現在0角標未知。
例:選擇排序
class shuzu3
{
public static void main(String[] args)
{
int [] arr = new int [] {1,4,6,99,10};
System.out.println("排序前");
prin (arr);
tst (arr);
System.out.println("排序後");
prin (arr);
}
//定義一個打印數組列表的方法。
public static void prin (int prin [])
{
for (int x=0;x<prin.length ;x++ )
{
if (x!=prin.length-1)
{//定義一個條件,給數字後麵加上逗號,如果是最後一個數字不加逗號並且換行。
System.out.print(prin[x]+" ");
//如果x不等於數組中的最後一個數組打印數字並加逗號
else
System.out.print(prin[x]);
//如果x不滿足上麵條件打印x
}
System.out.println();//換行操作。
}
//選擇排序循環
public static void tst (int arr[])
{
for (int x=0;x<arr.length ;x++ )
{
for (int y=x+1;y<arr.length ;y++ )
/*
因為x=0是0角標,所以y應該是1,但是當內循環完成後,
當再次進入內循環時,y仍然等於1,所以y必須要等於x+1
才能保證每次x都是和後麵一個角標進行比較
*/
{
if (arr[x]>arr[y])
{
int temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
//通過使用temp第三方變量的方式是數組中的元素進行換位操作。
}
}
}
}
}
7、冒泡排序
class shuzu5
{
public static void main(String[] args)
{
int [] maopao = new int [] {1,3,5,4,6,7,9};
System.out.println("排序前");
// Arrays.sort(maopao);
printarry (maopao);
arrypaixu (maopao);
System.out.println("排序後");
printarry (maopao);
}
//定義一個方法,實現角標的排序
public static void arrypaixu (int [] maopao)
{
for (int x=0;x<maopao.length-1 ;x++ )
{//maopao.length-1表示最後一個數值不用比較。外循環定義比較次數。
for (int y=0;y<maopao.length-x-1 ;y++ )
{//-x:表示每次都減少一個比較的數值,-1表示最後的數值不用比較。定義比較數值。
if (maopao[y]>maopao[y+1])
{//設立條件,第y個角標和第y個角標+1進行比較。如果是小於則為倒序。
int temp=maopao[y]; //角標換位
maopao[y]=maopao[y+1];
maopao[y+1]=temp;
}
}
}
}
public static void printarry (int [] maopao)
{
for (int x=0;x<maopao.length ;x++ ) //定一個循環語句進行遍曆,
{
if (x!=maopao.length-1)
{//定義一個條件,給數字後麵加上逗號,如果是最後一個數字不加逗號並且換行。
System.out.print(maopao[x]+", ");
}//如果x不等於數組中的最後一個數組打印數字並加逗號
else
System.out.print(maopao[x]);//如果x不滿足上麵條件打印x
}
System.out.println();//換行操作。
}
}
/*
冒泡和選擇排序效率比較低,因為都是在堆內存中進行的。
*/
8、上麵兩個例子中都出現了數組元素對調的功能,所以直接定義成一個包含該功能的函數
//數組元素位置對調函數。
public static void swap (int [] arr, int a, int b)
{
if (arr[a]>arr[b])
{
int temp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}
}
9、數組的查找,查找一個元素在數組中的位置。
例1:普通查找
class shuzu3
{
public static void main(String[] args)
{
int [] arr = new int [] {1,4,6,99,10};
int getnum = search (arr,99);
System.out.println("GetNum="+getnum);
}
//定義一個遍曆數組,並判斷傳入的key的角標,然後返回該角標的函數。如果該元素不存在則返回-1。
public static int search (int arr [],int key)
{
for (int x=0;x<arr.length ;x++ )
{
if (arr[x]==key)
return x;
}
return -1;
}
}
例2、折半查找方法1
class shuzu6
{
public static void main(String[] args)
{//當數組中有兩個相同的數值時,找到的是第一個出現的值。
int [] arr=new int []{1,2,3,4,5,6,7,9};
int b=zheban (arr,30);//定義一個折半查找的數值
System.out.println("b="+b);//打印查找出來的數值。
System.out.println("=================================");
}
/*
折半查找確定範圍。隻能查找有序的數組。
*/
public static int zheban(int []arr, int key)
{//定義一個方法,用來查找數組中數值的位置。
int min,mid,max;//定義最小值,中間值,最大值,來判斷數值所在的範圍。
min =0;//起始最小值為0
max=arr.length-1;//最大值等於,數組個數-1。
mid=(min+max)/2;//中間值,等於最小值加最大值除2.
while (key!=arr [mid]) //使用while語句直接判斷循環條件。
{
if (key>arr[mid])//使用條件選擇語句,判斷範圍。
min=mid+1;//使最小值上的指針向右移動
else if (key<arr [mid])//不知道是否能夠直接寫else,而不寫else if???
max=mid-1;//使最大值的指針向做移動。
if (min>max) //當輸入的數值大時,會陷入死循環,因為key永遠不等於arr [mid]
return -1;//返回一個-1表示,數值不存在。
mid=(min+max)/2;//第二次折半查找。
//注意上麵的key不要寫成arr[key],因為key是一個數值,而不是角標。
}
return mid;//返回的中間值即使,數值所在的位置。
}
}
例2、折半查找方法2
class shuzu6
{
public static void main(String[] args)
{//當數組中有兩個相同的數值時,找到的是第一個出現的值。
int [] arr=new int []{1,2,3,4,5,6,7,9};
int c=zheban2 (arr,3);
System.out.println("c="+c);//打印查找出來的數值。
}
//普通查找,一個一個數值查找
//定義一個查找數組的功能。一個未知的數組,和一個未知的要查找的數。
public static int getshuzu (int [] arr,int key)
{//查找一個數值在數組中的位置。
for (int x=0;x<arr.length;x++ )//遍曆數組,
{
if (arr[x]==key)//如果這個數組中的數值和key相等返回X
{
return x;
}
}
return -1;//如果沒有默認返回-1
}
/*
第二種折半方式
*/
public static int zheban2 (int []arr , int key)
{
int min =0 ,max=arr.length-1, mid;
while (min<=max)//當最小值小於等於最大值的時候循環
{
mid =(min+max)/2; //當中間值等於先進行折半,找出中間值。
if (key>arr[mid])//如果要查找的值大於了中間值
min=mid+1;//最小值向右移動,等於中間值加一
//否則如果,要查找的值小於了中間值,最大值的指針向左移動。最大值=mid-1
else if (key<arr[mid])
max=mid-1;
else
return mid;
}
return -1;
}
例3:
class shuzu6
{
public static void main(String[] args)
{//當數組中有兩個相同的數值時,找到的是第一個出現的值。
int [] arr=new int []{1,2,3,4,5,6,7,9};
int d=zheban3 (arr,8);//定義一個折半查找的數值
System.out.println("d="+d);//打印查找出來的數值。
}
/*
麵試題練習,有一個數值,找到這個數值應插入數組中的位置,並使數組有序。
思路,需要進行遍曆,查找數組,並且判斷這個數值應該大於min並且小於max,
也就是mid,但是這個mid是循環後最後一個mid。
*/
public static int zheban3 (int [] arr, int key)
{
int min=0, max=arr.length-1, mid;
while (min<=max)
{
mid=(min+max)/2;
if (key>arr[mid])
min=mid+1;
else if (key<arr[mid])
max=mid-1;
else
return mid ;
}
return min;//當返回最小值時既是這個數值應插入的位置。
}
}
10、進製轉換
例1、十進製轉二進製
class shuzu3
{
public static void main(String[] args)
{
to2 (2);
}
public static void to2 (int num)
{
StringBuffer SB= new StringBuffer (); //定義一個容器用來存儲num % 2的結果
while (num>0)
{
SB.append(num % 2); //將num % 2的結果存到容器中
num = num /2;
}
System.out.println(SB.reverse()); //翻轉打印SB.reverse()的內容
}
}
例2、十進製轉換十六進製
class shuzu3
{
public static void main(String[] args)
{
to16 (60);
}
public static void to16 (int num)
{
for (int x=0;x<8 ;x++ ) //因為一共是8個4位,所以右移做多8次。
{
int temp = num & 15; //temp是num&15的結果。
if (temp>9)
System.out.print((char)(temp-10+'A'));
else
System.out.print(temp);
num = num >>>4; //num是傳入的值右移4位的結果。
}
}
}
十進製==>>十六進製
取最低4位,算一個值,再取下一個四位,算一個值
60的二進製:0000-0000 0000-0000 0000-0000 0011-1100
0000-0000 0000-0000 0000-0000 0011-1100 ==>>60
& 0000-0000 0000-0000 0000-0000 0000-1111 ==>>15
---------------------------------------------------------------------------------
0000-0000 0000-0000 0000-0000 0000-1100 ==>>12==>>C
0000-0000 0000-0000 0000-0000 0011-1100 >>>無符號右移
---------------------------------------------------------------------------------
0000-0000 0000-0000 0000-0000 0000-0011右移後等於3
60的十六進製為3C
輸出結果:
D:\Skill\JAVA\2017>java shuzu3
C3000000
D:\Skill\JAVA\2017>
例3、因為例2的輸出結果不理想繼續優化。
class shuzu3
{
public static void main(String[] args)
{
to16 (60);
}
public static void to16 (int num)
{
StringBuffer SB = new StringBuffer(); //定義一個SB的容器用來存儲每次循環的值
for (int x=0;x<8 ;x++ ) //因為最多8個4位所以,最多循環8次
{
int temp = num & 15; //temp是num&15的結果。
if (temp>9) //因為從10-15是A-F
SB.append ((char)(temp-10+'A')); //使用容器SB存儲temp的值,當大於9時,強製轉換為字符。
else
SB.append (temp); //使用容器SB存儲temp的值
num = num >>>4; //num是傳入的值右移4位的結果。
}
System.out.println (SB.reverse());
}
}
輸出結果:
D:\Skill\JAVA\2017>java shuzu3
0000003C
D:\Skill\JAVA\2017>
例4、因為例3的輸出結果還是帶了很多沒用的0,使用查表法繼續優化。
十六進製程序三:查表法
0,1,2,3,4,5,6,7,8,9,A, B, C, D, E, F
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
任何數與上15結果都在15之內。
可以把0-F的十六進製數存到一個數組的表裏麵。並且使用與15的結果,和右移的結果去找
數組表中角標對應的數字。
例如:60的十六進製3C C對應的是與完15後12對應的值,3是右移後對應的值。
思路:
可以通過數組的方式建立一個表。
class shuzu3
{
public static void main(String[] args)
{
to16 (60);
}
public static void to16 (int num)
{
char [] chs = {'0','1','2','3','4',
'5','6','7','8','9',
'A','B','C','D','E','F'};
//定義一個char類型的數組,因為裏麵有數字也有字母。
char [] chr = new char [8]; //因為隻有8個4位所以定義數組的長度為8,用來存儲查表出來的值。
int pos = 0; //定義一個指針,用來確定num & 15的結果所在的角標的值。
while (num!=0) //當num不等於0時循環,num是傳入的值,(也即是4個8位的值不能全是0)
{
int temp = num & 15; //定義一個temp變量,用來存儲num & 15這個角標值。
chr [pos++] = chs [temp]; //因為pos的角標是不斷增加的,所以必須要pos++(後加)
num = num >>>4;
}
for (int x=pos-1;x>=0 ;x-- ) //因為 x=pos-1所以是倒著打印的。從最大角標值向最小值循環。
/*因為這時的pos時有效值加1的位置,所以必須要減1(隻打印有效位),
並且,
1、角標是順序存儲的,所以正常順序需要從最大角標值打印。
2、如果從chr.length打印會出現空位。
*/
{
System.out.print(chr[x]);
}
}
}
例5、十六進製的數組表中包含了二進製、八進製數
將二進製查表法和十六進製查表法融合。
num是要轉換的數,base是要與上的數,offset是要右移的位數
二進製要與的數是1,右移1位;
十六進製要與的數是15,右移4位;
8進製要與的數是7,右移3位;
class shuzu3
{
public static void main(String[] args)
{
to2(60);
to8(60);
to16(60);
}
public static void JZZH (int num, int base, int offset) //num傳入的數值,base&的值,offset右移的值。
{
char [] chs = {'0','1','2','3','4',
'5','6','7','8','9',
'A','B','C','D','E','F'};
//定義一個char類型的數組,因為裏麵有數字也有字母。
char [] chr = new char [32]; //因為最多有32個二進製位所以定義數組的長度為32,用來存儲查表出來的值。
int pos = 0; //定義一個指針,用來確定num & 15的結果所在的角標的值。
while (num!=0) //當num不等於0時循環,num是傳入的值
{
int temp = num & base; //定義一個temp變量,用來存儲 num & base 這個角標值。
chr [pos++] = chs [temp]; //因為pos的角標是不斷增加的,所以必須要pos++(後加)
num = num >>>offset;
}
for (int x=pos-1;x>=0 ;x-- ) //因為 x=pos-1所以是倒著打印的。從最大角標值向最小值循環。
/*因為這時的pos時有效值加1的位置,所以必須要減1(隻打印有效位),
並且,
1、角標是順序存儲的,所以正常順序需要從最大角標值打印。
2、如果從chr.length打印會出現空位。
*/
{
System.out.print(chr[x]);
}
}
public static void to2 (int num)
{
JZZH(num,1,1);
System.out.println();
System.out.println("二進製");
}
public static void to8 (int num)
{
JZZH(num,7,3);
System.out.println();
System.out.println("八進製");
}
public static void to16 (int num)
{
JZZH(num,15,4);
System.out.println();
System.out.println("十六進製");
}
}
11、二維數組
例1、
class shuzu
{
public static void main(String[] args)
{
int [] [] arr = new int [3] [4];
arr[0] [0] = 100;
arr[1] [3] = 200;
arr[2] [2] = 300;
int [] [] arr1 = new int [3] [];
System.out.println("Arr第一個小數組的第1個元素 "+arr[0][0]);
System.out.println("Arr第二個小數組的第4個元素 "+arr[1][3]);
System.out.println("Arr第三個小數組的第3個元素 "+arr[2][2]);
System.out.println("Arr1第三個小數組的第3個元素 "+arr1[2][2]); //因為隻初始化了二維數組的長度,沒有初始化二維數組中一維數組的長度,所以當打印一維數組時返回值為NULL
}
}
輸出結果:
D:\Skill\JAVA\2017>java shuzu
Arr第一個小數組的第1個元素 100
Arr第二個小數組的第4個元素 200
Arr第三個小數組的第3個元素 300
Exception in thread "main" java.lang.NullPointerException
at shuzu.main(shuzu.java:15)
D:\Skill\JAVA\2017>
例、二維數組中的元素求和(for嵌套循環)
class shuzu
{
public static void main(String[] args)
{
int num = 0;
int [] [] arr = {{1,2,3},{3,2,1},{4,5,6}};
for (int x=0;x<arr.length ;x++ ) //確定二維數組長度為arr.lgenth
{
for (int y=0;y<arr[x].length ;y++ ) //確定一維數組長度為arr[x].length
{
num = num + arr[x][y]; //求和。
}
}
System.out.println("Arr的元素和為: "+num);
}
}
特殊格式說明:
int [][]y; 二維數組
int []y[]; 二維數組
int []x,y[];這個相當於:
int []x;
int[]y[];
也就是定義了一個一維數組x;和一個二維數組y。
例、
a.
x[2]=y; 這句話的意思是把y這個二維數組賦值給x這個一維數組,肯定是錯誤的。
b.
y[0]=x; 這句話的意思是把x這個一維數組賦值到y這個二維數組,肯定OK
c.
y[0][0]=x; 這句話的意思是把一維數組對y二維數組中的元素,肯定錯誤
d.
x[0][0]=y; 這句話的意思是把y這個二維數組賦值給x二維數組中的一個元素,明顯不對。因為x是一維數組。
最後更新:2017-08-28 09:03:44