1. 語句
1.1 流程控制語句
在一個程序執(zhí)行的過程中勒葱,各條語句的執(zhí)行順序對程序的結果是有直接影響的。也就是說程序的流程對運行結果有直接的影響巴柿。所以凛虽,我們必須清楚每條語句的執(zhí)行流程。而且广恢,很多時候我們要通過控制語句的執(zhí)行順序來實現(xiàn)我們要完成的功能凯旋。
流程控制語句分類:順序結構、選擇結構钉迷、循環(huán)結構
1.2 順序結構概述
是程序中最簡單最基本的流程控制至非,沒有特定的語法結構,按照代碼的先后順序糠聪,依次執(zhí)行荒椭,程序中大多數(shù)的代碼都是這樣執(zhí)行的。
總的來說:寫在前面的先執(zhí)行枷颊,寫在后面的后執(zhí)行
1.3 選擇結構
選擇結構也被稱為分支結構戳杀。選擇結構有特定的語法規(guī)則该面,代碼要執(zhí)行具體的邏輯運算進行判斷,邏輯運算的結果有兩個信卡,所以產生選擇隔缀,按照不同的選擇執(zhí)行不同的代碼。
Java語言提供了兩種選擇結構語句:(1)if語句(2)switch語句
1.3.1 選擇結構(if語句)
if語句有三種格式
if語句第一種格式:
if(關系表達式) {
語句體
}
執(zhí)行流程:
- 首先判斷關系表達式看其結果是true還是false
- 如果是true就執(zhí)行語句體
- 如果是false就不執(zhí)行語句體
注意事項:
- 關系表達式無論簡單還是復雜傍菇,結果必須是boolean類型
- if語句控制的語句體如果是一條語句猾瘸,大括號可以省略;如果是多條語句丢习,就不能省略牵触。建議永遠不要省略。
- 一般來說:有左大括號就沒有分號咐低,有分號就沒有左大括號
if語句第二種格式:
if(關系表達式) {
語句體1;
}else {
語句體2;
}
執(zhí)行流程:
首先判斷關系表達式看其結果是true還是false
如果是true就執(zhí)行語句體1
如果是false就執(zhí)行語句體2
/*
if語句格式2的練習:
A:獲取兩個數(shù)據(jù)中較大的值
B:判斷一個數(shù)據(jù)是奇數(shù)還是偶數(shù),并輸出是奇數(shù)還是偶數(shù)
*/
import java.util.Scanner;
class IfTest {
public static void main(String[] args) {
//創(chuàng)建鍵盤錄入對象
Scanner sc = new Scanner(System.in);
//獲取兩個數(shù)據(jù)中較大的值
System.out.println("請輸入第一個數(shù)據(jù):");
int a = sc.nextInt();
System.out.println("請輸入第二個數(shù)據(jù):");
int b = sc.nextInt();
//定義一個變量接收最大值
int max;
if(a > b) {
max = a;
}else {
max = b;
}
System.out.println("max:"+max);
System.out.println("----------------");
//判斷一個數(shù)據(jù)是奇數(shù)還是偶數(shù)
System.out.println("請輸入你要判斷的數(shù)據(jù):");
int x = sc.nextInt();
if(x%2 == 0) {
System.out.println(x+"這個數(shù)據(jù)是偶數(shù)");
}else {
System.out.println(x+"這個數(shù)據(jù)是奇數(shù)");
}
}
}
運行結果:
if語句第三種格式:
if(關系表達式1) {
語句體1;
}else if (關系表達式2) {
語句體2;
}
…
else {
語句體n+1;
}
執(zhí)行流程:
- 首先判斷關系表達式1看其結果是true還是false
- 如果是true就執(zhí)行語句體1
- 如果是false就繼續(xù)判斷關系表達式2看其結果是true還是false
- 如果是true就執(zhí)行語句體2
- 如果是false就繼續(xù)判斷關系表達式…看其結果是true還是false
… - 如果沒有任何關系表達式為true揽思,就執(zhí)行語句體n+1。
/*
三種if語句分別適合做什么事情呢?
格式1:適合做單個判斷
格式2:適合做兩個判斷
格式3:適合做多個判斷
需求:
鍵盤錄入x的值见擦,計算出y的并輸出钉汗。
x>=3 y = 2x + 1;
-1<=x<3 y = 2x;
x<=-1 y = 2x – 1;
分析:
A:由于數(shù)據(jù)要鍵盤錄入,所以必須使用Scanner鲤屡。
B:由于是三種判斷损痰,所以我們選擇if語句格式3。
*/
import java.util.Scanner;
class IfTest2 {
public static void main(String[] args) {
//創(chuàng)建鍵盤錄入對象
Scanner sc = new Scanner(System.in);
System.out.println("請輸入x的值:");
int x = sc.nextInt();
//定義一個y
int y;
//用if語句格式3進行判斷
if(x >= 3) {
y = 2*x + 1;
}else if(x>=-1 && x<3) {
y = 2*x;
}else {
y = 2*x - 1;
}
System.out.println("y:"+y);
}
}
運行結果:
switch語句格式:
switch(表達式) {
case 值1:
語句體1;
break;
case 值2:
語句體2;
break;
…
default:
語句體n+1;
break;
}
格式解釋
- switch表示這是switch語句
- 表達式的取值:byte酒来,short卢未,int,char
- JDK5以后可以是枚舉
- JDK7以后可以是String
- case后面跟的是要和表達式進行比較的值
- 語句體部分可以是一條或多條語句
- break表示中斷堰汉,結束的意思辽社,可以結束switch語句
- default語句表示所有情況都不匹配的時候,就執(zhí)行該處的內容衡奥,和if語句的else相似爹袁。
執(zhí)行流程
- 首先計算出表達式的值
- 其次,和case依次比較矮固,一旦有對應的值失息,就會執(zhí)行相應的語句,在執(zhí)行的過程中档址,遇到break就會結束盹兢。
- 最后,如果所有的case都和表達式的值不匹配守伸,就會執(zhí)行default語句體部分绎秒,然后程序結束掉。
/*
用switch語句實現(xiàn)鍵盤錄入月份尼摹,輸出對應的季節(jié)
分析:
A:鍵盤錄入一個月份见芹,用Scanner實現(xiàn)
B:用switch語句實現(xiàn)即可
*/
import java.util.Scanner;
class SwitchTest4 {
public static void main(String[] args) {
//創(chuàng)建鍵盤錄入對象
Scanner sc = new Scanner(System.in);
//錄入數(shù)據(jù)
System.out.println("請輸入月份(1-12):");
int month = sc.nextInt();
//case穿透
switch(month) {
case 1:
case 2:
case 12:
System.out.println("冬季");
break;
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
default:
System.out.println("你輸入的月份有誤");
}
}
}
運行結果:
(3)if語句和switch語句的區(qū)別?
if語句:
- A:針對結果是boolean類型的判斷
- B:針對一個范圍的判斷
- C:針對幾個常量值的判斷
switch語句:針對幾個常量值的判斷
注意事項:
- case后面只能是常量剂娄,不能是變量,而且玄呛,多個case后面的值不能出現(xiàn)相同的
- default可以省略嗎?可以省略阅懦。一般不建議。除非判斷的值是固定的徘铝。
- break可以省略嗎?可以省略耳胎,一般不建議。否則結果可能不是你想要的
- default的位置一定要在最后嗎?可以出現(xiàn)在switch語句任意位置惕它。
- switch語句的結束條件怕午,遇到break執(zhí)行到程序的末尾
2. 循環(huán)結構
循環(huán)語句可以在滿足循環(huán)條件的情況下,反復執(zhí)行某一段代碼淹魄,這段被重復執(zhí)行的代碼被稱為循環(huán)體語句郁惜,當反復執(zhí)行這個循環(huán)體時,需要在合適的時候把循環(huán)判斷條件修改為false揭北,從而結束循環(huán)扳炬,否則循環(huán)將一直執(zhí)行下去,形成死循環(huán)搔体。
2.1 循環(huán)語句的組成
- 初始化語句:一條或者多條語句,這些語句完成一些初始化操作
- 判斷條件語句:這是一個boolean 表達式半醉,這個表達式能決定是否執(zhí)行循環(huán)體
- 循環(huán)體語句:這個部分是循環(huán)體語句疚俱,也就是我們要多次做的事情
- 控制條件語句:這個部分在一次循環(huán)體結束后,下一次循環(huán)判斷條件執(zhí)行前執(zhí)行缩多。通過用于控制循環(huán)條件中的變量呆奕,使得循環(huán)在合適的時候結束
2.2 for循環(huán)語句格式
for(初始化語句;判斷條件語句;控制條件語句) {
循環(huán)體語句;
}
執(zhí)行流程
- 執(zhí)行初始化語句
- 執(zhí)行判斷條件語句,看其結果是true還是false
- 如果是false衬吆,循環(huán)結束
- 如果是true梁钾,繼續(xù)執(zhí)行
- 執(zhí)行循環(huán)體語句
- 執(zhí)行控制條件語句
- 回到B繼續(xù)
注意事項
判斷條件語句的結果是一個boolean類型
循環(huán)體語句如果是一條語句,大括號可以省略逊抡;如果是多條語句姆泻,大括號不能省略。建議永遠不要省略冒嫡。
一般來說:有左大括號就沒有分號拇勃,有分號就沒有左大括號
2.3 for語句的練習
代碼示例:在控制臺輸出所有的”水仙花數(shù)”
/*
需求:在控制臺輸出所有的”水仙花數(shù)”
分析:
我們都不知道什么叫"水仙花數(shù)",你讓我怎么做呢?
所謂的水仙花數(shù)是指一個三位數(shù)孝凌,其各位數(shù)字的立方和等于該數(shù)本身方咆。
舉例:153就是一個水仙花數(shù)。
153 = 1*1*1 + 5*5*5 + 3*3*3 = 1 + 125 + 27 = 153
A:三位數(shù)其實是告訴了我們范圍蟀架。
B:通過for循環(huán)我們就可以實現(xiàn)獲取每一個三位數(shù)
但是麻煩是如何獲取這個三位數(shù)的個,十,百位上的數(shù)據(jù)
我們如何獲取一個數(shù)據(jù)的個,十,百呢?
假設有個一個數(shù)據(jù):153
ge: 153%10 = 3
shi: 153/10%10 = 5
bai:153/10/10%10 = 1
qian:x/10/10/10%10
wan: x/10/10/10/10%10
...
C:讓ge*ge*ge+shi*shi*shi+bai*bai*bai和該數(shù)據(jù)比較
如果相同瓣赂,就把該數(shù)據(jù)在控制臺輸出榆骚。
*/
class ForDemo6 {
public static void main(String[] args) {
//三位數(shù)其實是告訴了我們范圍。
for(int x=100; x<1000; x++) {
int ge = x%10;
int shi = x/10%10;
int bai = x/10/10%10;
//讓ge*ge*ge+shi*shi*shi+bai*bai*bai和該數(shù)據(jù)比較
if(x == (ge*ge*ge+shi*shi*shi+bai*bai*bai)) {
//如果相同煌集,就把該數(shù)據(jù)在控制臺輸出寨躁。
System.out.println(x);
}
}
}
}
運行結果:
代碼示例:回文數(shù)
/*
練習:
請在控制臺輸出滿足如下條件的五位數(shù)
個位等于萬位
十位等于千位
個位+十位+千位+萬位=百位
分析:
A:五位數(shù)就告訴了我們范圍。
B:分解每一個五位數(shù)的個牙勘,十职恳,百,千方面,萬位上的數(shù)據(jù)
C:按照要求進行判斷即可
*/
class ForDemo7 {
public static void main(String[] args) {
//五位數(shù)就告訴了我們范圍放钦。
for(int x=10000; x<100000; x++) {
//分解每一個五位數(shù)的個,十恭金,百操禀,千,萬位上的數(shù)據(jù)
int ge = x%10;
int shi = x/10%10;
int bai = x/10/10%10;
int qian = x/10/10/10%10;
int wan = x/10/10/10/10%10;
//按照要求進行判斷即可
if((ge==wan) && (shi==qian) && (ge+shi+qian+wan==bai)) {
System.out.println(x);
}
}
}
}
運行結果:
2.4 while循環(huán)語句格式
基本格式
while(判斷條件語句) {
循環(huán)體語句;
}
擴展格式
初始化語句;
while(判斷條件語句) {
循環(huán)體語句;
控制條件語句;
}
循環(huán)結構(for循環(huán)和while循環(huán)的區(qū)別)
for循環(huán)語句和while循環(huán)語句可以等價轉換横腿,但還是有些小區(qū)別的
- 使用區(qū)別:控制條件語句所控制的那個變量颓屑,在for循環(huán)結束后,就不能再被訪問到了耿焊,而while循環(huán)結束還可以繼續(xù)使用揪惦,如果你想繼續(xù)使用,就用while罗侯,否則推薦使用for器腋。原因是for循環(huán)結束,該變量就從內存中消失钩杰,能夠提高內存的使用效率纫塌。
- 場景區(qū)別:for循環(huán)適合針對一個范圍判斷進行操作,while循環(huán)適合判斷次數(shù)不明確操作
/*
練習:用while循環(huán)實現(xiàn)
左邊:求出1-100之和
右邊:統(tǒng)計水仙花數(shù)有多少個
初始化語句;
while(判斷條件語句) {
循環(huán)體語句;
控制條件語句;
}
for(初始化語句;判斷條件語句;控制條件語句) {
循環(huán)體語句;
}
*/
class WhileDemo2 {
public static void main(String[] args) {
//求出1-100之和
//for語句版本
int sum = 0;
for(int x=1; x<=100; x++) {
sum+=x;
}
System.out.println("sum:"+sum);
System.out.println("--------");
//while語句版本
int sum2 = 0;
int y=1;
while(y<=100) {
sum2+=y;
y++;
}
System.out.println("sum2:"+sum2);
System.out.println("--------");
}
}
運行結果:
/*
需求:統(tǒng)計水仙花數(shù)有多少個
*/
class WhileDemo3 {
public static void main(String[] args) {
//for循環(huán)版本
int count = 0;
for(int x=100; x<1000; x++) {
int ge = x%10;
int shi = x/10%10;
int bai = x/10/10%10;
if((ge*ge*ge+shi*shi*shi+bai*bai*bai) == x) {
count++;
}
}
System.out.println("count:"+count);
System.out.println("------------");
//while循環(huán)版本
int count2 = 0;
int y = 100;
while(y<1000) {
int ge = y%10;
int shi = y/10%10;
int bai = y/10/10%10;
if((ge*ge*ge+shi*shi*shi+bai*bai*bai) == y) {
count2++;
}
y++;
}
System.out.println("count2:"+count2);
}
}
運行結果:
2.4 while循環(huán)和for循環(huán)的區(qū)別?
使用區(qū)別:如果你想在循環(huán)結束后,繼續(xù)使用控制條件的那個變量讲弄,用while循環(huán)措左,否則用for循環(huán)。不知道用for循環(huán)避除。因為變量及早的從內存中消失怎披,可以提高內存的使用效率。
其實還有一種場景的理解:
如果是一個范圍的驹饺,用for循環(huán)非常明確钳枕。
如果是不明確要做多少次,用while循環(huán)較為合適赏壹。舉例:吃葡萄鱼炒。
class WhileDemo4 {
public static void main(String[] args) {
//for循環(huán)實現(xiàn)
for(int x=0; x<10; x++) {
System.out.println("學習Java技術哪家強,中國北京傳智播客");
}
//這里不能在繼續(xù)訪問了
//System.out.println(x);
//while循環(huán)實現(xiàn)
int y = 0;
while(y<10) {
System.out.println("學習Java技術哪家強,中國北京傳智播客");
y++;
}
//這里是可以繼續(xù)訪問的
System.out.println(y);
}
}
2.5 do…while循環(huán)語句格式
基本格式
do {
循環(huán)體語句;
}while((判斷條件語句);
擴展格式
初始化語句;
do {
循環(huán)體語句;
控制條件語句;
} while((判斷條件語句);
注意死循環(huán):
A:一定要注意控制條件語句控制的那個變量的問題,不要弄丟了蝌借,否則就容易死循環(huán)昔瞧。
B:兩種最簡單的死循環(huán)格式
while(true){...}
for(;;){...}
2.6 循環(huán)嵌套
代碼示例:九九表
/*
需求:在控制臺輸出九九乘法表指蚁。
首先我們寫出九九乘法表:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
...
1*9=9 2*9=18 3*9=27 ...
我們先把這個九九乘法表看出是這樣的一個形狀:
*
**
***
****
*****
******
*******
********
*********
注意:
'\x' x表示任意,這種做法叫轉移字符自晰。
'\t' tab鍵的位置
'\r' 回車
'\n' 換行
*/
class ForForDemo3 {
public static void main(String[] args) {
for(int x=0; x<9; x++) {
for(int y=0; y<=x; y++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("--------------");
//為了使用數(shù)據(jù)凝化,我們從1開始
for(int x=1; x<=9; x++) {
for(int y=1; y<=x; y++) {
System.out.print(y+"*"+x+"="+y*x+"\t");
}
System.out.println();
}
}
}
運行結果:
2.7 跳轉控制語句
Java中的goto是保留字,目前不能使用酬荞。雖然沒有goto語句可以增強程序的安全性搓劫,但是也帶來很多不便,比如說混巧,我想在某個循環(huán)知道到某一步的時候就結束枪向,現(xiàn)在就做不了這件事情。為了彌補這個缺陷咧党,Java就提供了break秘蛔,continue和return來實現(xiàn)控制語句的跳轉和中斷。
break 中斷傍衡、continue 繼續(xù)深员、return 返回
2.7.1 break的使用場景
- 在選擇結構switch語句中
- 在循環(huán)語句中
- 離開使用場景的存在是沒有意義的
2.7.2 break的作用
- 跳出單層循環(huán)
- 跳出多層循環(huán)
帶標簽的跳出
格式:標簽名: 循環(huán)語句
標簽名要符合Java的命名規(guī)則
/*
控制跳轉語句:
break:中斷
continue:繼續(xù)
return:返回
break:中斷的意思
使用場景:
A:switch語句中
B:循環(huán)語句中。
(循環(huán)語句中加入了if判斷的情況)
注意:離開上面的兩個場景蛙埂,無意義倦畅。
如何使用呢?
A:跳出單層循環(huán)
B:跳出多層循環(huán)
要想實現(xiàn)這個效果,就必須知道一個東西箱残。帶標簽的語句滔迈。
格式:
標簽名: 語句
*/
class BreakDemo {
public static void main(String[] args) {
//在 switch 或 loop 外部中斷
//break;
//跳出單層循環(huán)
for(int x=0; x<10; x++) {
if(x == 3) {
break;
}
System.out.println("HelloWorld");
}
System.out.println("over");
System.out.println("-------------");
wc:for(int x=0; x<3; x++) {
nc:for(int y=0; y<4; y++) {
if(y == 2) {
//break nc;
break wc;
}
System.out.print("*");
}
System.out.println();
}
}
}
2.7.3 continue的使用場景
- 在循環(huán)語句中
- 離開使用場景的存在是沒有意義的
2.7.4 continue的作用
- 單層循環(huán)對比break,然后總結兩個的區(qū)別
- break 退出當前循環(huán)
- continue 退出本次循環(huán)
- 也可以帶標簽的使用
/*
continue:繼續(xù)
使用場景:
循環(huán)中被辑。離開此場景無意義。
測試敬惦,找到和break的區(qū)別:
break:跳出單層循環(huán)
continue:跳出一次循環(huán)盼理,進入下一次的執(zhí)行
練習題:
for(int x=1; x<=10; x++) {
if(x%3==0) {
//在此處填寫代碼
}
System.out.println(“Java基礎班”);
}
我想在控制臺輸出2次:“Java基礎班“
break;
我想在控制臺輸出7次:“Java基礎班“
continue;
我想在控制臺輸出13次:“Java基礎班“
System.out.println(“Java基礎班”);
*/
class ContinueDemo {
public static void main(String[] args) {
for(int x=0; x<10; x++) {
if(x == 3) {
//break;
continue;
}
System.out.println(x);
}
}
}
2.7.5 return關鍵字
不是為了跳轉出循環(huán)體,更常用的功能是結束一個方法俄删,也就是退出一個方法宏怔。跳轉到上層調用的方法。這個在方法的使用那里會在詳細的講解
/*
return:返回
其實它的作用不是結束循環(huán)的畴椰,而是結束方法的臊诊。
*/
class ReturnDemo {
public static void main(String[] args) {
for(int x=0; x<10; x++) {
if(x == 2) {
System.out.println("退出");
//break;
//continue;
return;
}
System.out.println(x);
}
System.out.println("over");
}
}
3. 方法
3.1 方法概述
假設有一個游戲程序,程序在運行過程中斜脂,要不斷地發(fā)射炮彈(植物大戰(zhàn)僵尸)抓艳。發(fā)射炮彈的動作需要編寫100行的代碼,在每次實現(xiàn)發(fā)射炮彈的地方都需要重復地編寫這100行代碼帚戳,這樣程序會變得很臃腫玷或,可讀性也非常差儡首。為了解決代碼重復編寫的問題,可以將發(fā)射炮彈的代碼提取出來放在一個{}中偏友,并為這段代碼起個名字蔬胯,這樣在每次發(fā)射炮彈的地方通過這個名字來調用發(fā)射炮彈的代碼就可以了。上述過程中位他,所提取出來的代碼可以被看作是程序中定義的一個方法氛濒,程序在需要發(fā)射炮彈時調用該方法即可。
3.2 方法定義及格式
1鹅髓、簡單的說:方法就是完成特定功能的代碼塊
在很多語言里面都有函數(shù)的定義舞竿,函數(shù)在Java中被稱為方法
2、格式:
修飾符 返回值類型 方法名(參數(shù)類型 參數(shù)名1迈勋,參數(shù)類型 參數(shù)名2…) {
函數(shù)體;
return 返回值;
}
3.3 方法格式解釋
- 修飾符 比較多炬灭,后面會詳細介紹。目前public static
- 返回值類型 用于限定返回值的數(shù)據(jù)類型
- 方法名 一個名稱靡菇,為了方便我們調用方法
- 參數(shù)類型 限定調用方法時傳入?yún)?shù)的數(shù)據(jù)類型
- 參數(shù)名 是一個變量重归,接收調用方法時傳入的參數(shù)
- 方法體 完成功能的代碼
- return 結束方法以及返回方法指定類型的值
- 返回值 程序被return帶回的結果,返回給調用者
3.4 有明確返回值的方法調用
- 單獨調用厦凤,沒有意義
- 輸出調用鼻吮,有意義,但是不夠好较鼓,因為我不一定非要把結果輸出
- 賦值調用椎木,推薦方式
注意事項:
- 方法不調用不執(zhí)行
- 方法與方法是平級關系,不能嵌套定義
- 方法定義的時候參數(shù)之間用逗號隔開
- 方法調用的時候不用在傳遞數(shù)據(jù)類型
- 如果方法有明確的返回值博烂,一定要有return帶回一個值
3.5 沒有明確返回值的函數(shù)調用
- 其實就是void類型方法的調用
- 只能單獨調用
3.6 方法調用圖解
3.7 方法重載
-
方法重載概述
在同一個類中香椎,允許存在一個以上的同名方法,只要它們的參數(shù)個數(shù)或者參數(shù)類型不同即可禽篱。
-
方法重載特點
與返回值類型無關畜伐,只看方法名和參數(shù)列表
在調用時,虛擬機通過參數(shù)列表的不同來區(qū)分同名方法
/*
比較兩個數(shù)據(jù)是否相等躺率。參數(shù)類型分別為
兩個byte類型玛界,兩個short類型,兩個int類型悼吱,兩個long類型慎框,
并在main方法中進行測試
*/
class FunctionTest6 {
public static void main(String[] args) {
//測試
byte b1 = 3;
byte b2 = 4;
System.out.println("byte:"+compare(b1,b2));
//測試
short s1 = 5;
short s2 = 5;
System.out.println("short:"+compare(s1,s2));
//后面的兩個自己測試
}
//byte類型
public static boolean compare(byte a,byte b) {
System.out.println("byte");
return a == b;
}
//short類型
public static boolean compare(short a,short b) {
System.out.println("short");
return a == b;
}
//int類型
public static boolean compare(int a,int b) {
System.out.println("int");
return a == b;
}
//long類型
public static boolean compare(long a,long b) {
System.out.println("long");
return a == b;
}
}
運行結果:
4. 數(shù)組
4.1 數(shù)組概述
需求:現(xiàn)在需要統(tǒng)計某公司員工的工資情況,例如計算平均工資后添、找到最高工資等笨枯。假設該公司有80名員工,用前面所學的知識,程序首先需要聲明80個變量來分別記住每位員工的工資猎醇,然后在進行操作窥突,這樣做會顯得很麻煩。為了解決這種問題硫嘶,Java就提供了數(shù)組供我們使用
那么數(shù)組到底是什么呢?有什么特點呢?通過上面的分析:我們可以得到如下兩句話:
- 數(shù)組是存儲多個變量(元素)的東西(容器)
- 這多個變量的數(shù)據(jù)類型要一致
4.2 數(shù)組概念
- 數(shù)組是存儲同一種數(shù)據(jù)類型多個元素的集合阻问。也可以看成是一個容器
- 數(shù)組既可以存儲基本數(shù)據(jù)類型,也可以存儲引用數(shù)據(jù)類型
4.3 數(shù)組的定義格式
格式1:數(shù)據(jù)類型[] 數(shù)組名;
格式2:數(shù)據(jù)類型 數(shù)組名[];
注意:這兩種定義做完了沦疾,數(shù)組中是沒有元素值的
4.4 數(shù)組初始化概述
- Java中的數(shù)組必須先初始化,然后才能使用
- 所謂初始化:就是為數(shù)組中的數(shù)組元素分配內存空間称近,并為每個數(shù)組元素賦值
- 數(shù)組的初始化方式
- 動態(tài)初始化:初始化時只指定數(shù)組長度,由系統(tǒng)為數(shù)組分配初始值哮塞。
- 靜態(tài)初始化:初始化時指定每個數(shù)組元素的初始值刨秆,由系統(tǒng)決定數(shù)組長度
- 動態(tài)初始化:初始化時只指定數(shù)組長度,由系統(tǒng)為數(shù)組分配初始值
格式:數(shù)據(jù)類型[] 數(shù)組名 = new 數(shù)據(jù)類型[數(shù)組長度];
數(shù)組長度其實就是數(shù)組中元素的個數(shù)忆畅。
舉例:int[] arr = new int[3];
解釋:定義了一個int類型的數(shù)組衡未,這個數(shù)組中可以存放3個int類型的值。
4.5 Java中的內存分配
Java 程序在運行時家凯,需要在內存中的分配空間缓醋。為了提高運算效率,就對空間進行了不同區(qū)域的劃分绊诲,因為每一片區(qū)域都有特定的處理數(shù)據(jù)方式和內存管理方式送粱。
- 棧 存儲局部變量
- 堆 存儲new出來的東西
- 方法區(qū) (面向對象部分講)
- 本地方法區(qū) (和系統(tǒng)相關)
- 寄存器 (給CPU使用)
4.6 Java中數(shù)組的內存圖解
圖解1:定義一個數(shù)組,輸出數(shù)組名及元素掂之。然后給數(shù)組中的元素賦值抗俄,再次輸出數(shù)組名及元素。
圖解2:定義兩個數(shù)組世舰,分別輸出數(shù)組名及元素动雹。然后分別給數(shù)組中的元素賦值,分別再次輸出數(shù)組名及元素跟压。
圖解3:定義兩個數(shù)組洽胶,先定義一個數(shù)組,賦值裆馒,輸出。然后定義第二個數(shù)組的時候把第一個數(shù)組的地址賦值給第二個數(shù)組丐怯。然后給第二個數(shù)組賦值喷好,再次輸出兩個數(shù)組的名及元素。
4.7 數(shù)組的初始化
靜態(tài)初始化:初始化時指定每個數(shù)組元素的初始值读跷,由系統(tǒng)決定數(shù)組長度梗搅。
格式:數(shù)據(jù)類型[] 數(shù)組名 = new 數(shù)據(jù)類型[]{元素1,元素2,…};
舉例:int[] arr = new int[]{1,2,3};
解釋:定義了一個int類型的數(shù)組,這個數(shù)組中可以存放3個int類型的值,并且值分別是1,2,3无切。
其實這種寫法還有一個簡化的寫法:int[] arr = {1,2,3};
4.8 數(shù)組操作常見的兩個小問題
- ArrayIndexOutOfBoundsException 數(shù)組索引越界
訪問到了數(shù)組中的不存在的索引時發(fā)生 - NullPointerException 空指針異常
數(shù)組引用沒有指向實體荡短,卻在操作實體中的元素時。
4.9 二維數(shù)組概述
二維數(shù)組概述
我們傳智播客的Java基礎班每個班有很多個學生哆键,所以掘托,可以用數(shù)組來存儲,而我們又同時有很多個Java基礎班籍嘹。這個也應該用一個數(shù)組來存儲闪盔。如何來表示這樣的數(shù)據(jù)呢?Java就提供了二維數(shù)組供我們使用。由此可見:其實二維數(shù)組其實就是一個元素為一維數(shù)組的數(shù)組辱士。
二維數(shù)組定義格式
(1)格式1
數(shù)據(jù)類型[][] 變量名 = new 數(shù)據(jù)類型[m][n];
// m表示這個二維數(shù)組有多少個一維數(shù)組
// n表示每一個一維數(shù)組的元素個數(shù)
舉例:
int[][] arr = new int[3][2];
// 定義了一個二維數(shù)組arr
// 這個二維數(shù)組有3個一維數(shù)組泪掀,名稱是arr[0],arr[1],arr[2]
// 每個一維數(shù)組有2個元素,可以通過arr[m][n]來獲取
// 表示獲取第m+1個一維數(shù)組的第n+1個元素
(2)格式2
數(shù)據(jù)類型[][] 變量名 = new 數(shù)據(jù)類型[m][];
// m表示這個二維數(shù)組有多少個一維數(shù)組
// 這一次沒有直接給出一維數(shù)組的元素個數(shù)颂碘,可以動態(tài)的給出异赫。
舉例:
int[][] arr = new int[3][];
arr[0] = new int[2];
arr[1] = new int[3]
arr[2] = new int[1];
(3)格式3
數(shù)據(jù)類型[][] 變量名 = new 數(shù)據(jù)類型[][]{{元素…},{元素…},{元素…}};
簡化版格式:數(shù)據(jù)類型[][] 變量名 = {{元素…},{元素…},{元素…}};
舉例:int[][] arr = {{1,2,3},{4,6},{6}};
4.10 數(shù)組常見操作
4.10.1 數(shù)組遍歷
/*
數(shù)組遍歷:就是依次輸出數(shù)組中的每一個元素。
注意:數(shù)組提供了一個屬性length头岔,用于獲取數(shù)組的長度塔拳。
格式:數(shù)組名.length
*/
class ArrayTest {
public static void main(String[] args) {
//定義數(shù)組
int[] arr = {11,22,33,44,55};
//獲取每一個元素
//如何獲取呢?我們知道數(shù)組名結合編號(索引)就可以找到數(shù)據(jù)
for(int x=0; x<5; x++) {
//x=0,1,2,3,4
System.out.println(arr[x]);
}
System.out.println("--------------------");
//從0開始我們是明確的,但是為什么到5呢切油,我們是數(shù)了一下數(shù)組的個數(shù)
//繼續(xù)看下個數(shù)組如何遍歷
int[] arr2 = {1,2,3,4,5,6,7,8,9,10,11,2,2,3,4,5,7,8,5,3,5,6,8,7,8,5,3,5,6,8,7,8,5,3,5,6,8,7,8,5,3,5,6,8,7,8,5,3,5,6,8};
//而我們在很多時候蝙斜,數(shù)組的元素不能靠數(shù)
//這個時候,數(shù)組就給我們提供了一個屬性:length專門用于獲取數(shù)組的長度
//格式:數(shù)組名.length 返回數(shù)組的長度
System.out.println(arr.length);
System.out.println(arr2.length);
System.out.println("--------------------");
//改進第一個程序
for(int x=0; x<arr.length; x++) {
System.out.println(arr[x]);
}
System.out.println("--------------------");
//我們如果想要對多個數(shù)組進行遍歷澎胡,每個數(shù)組的遍歷我們都把代碼寫一遍孕荠,麻煩不
//麻煩,所以攻谁,我們準備用方法改進稚伍。
//用方法改進后,請調用
printArray(arr);
System.out.println("--------------------");
printArray(arr2);
System.out.println("--------------------");
printArray2(arr);
}
/*
遍歷數(shù)組的方法
兩個明確:
返回值類型:void
參數(shù)列表:int[] arr
*/
public static void printArray(int[] arr) {
for(int x=0; x<arr.length; x++) {
System.out.println(arr[x]);
}
}
//請看改進版本
public static void printArray2(int[] arr) {
System.out.print("[");
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) { //這是最后一個元素
System.out.println(arr[x]+"]");
}else {
System.out.print(arr[x]+", ");
}
}
}
}
4.10.2 獲取數(shù)組最值
/*
數(shù)組獲取最值(獲取數(shù)組中的最大值最小值)
分析:
A:定義一個數(shù)組戚宦,并對數(shù)組的元素進行靜態(tài)初始化个曙。
B:從數(shù)組中任意的找一個元素作為參照物(一般取第一個),默認它就是最大值。
C:然后遍歷其他的元素受楼,依次獲取和參照物進行比較垦搬,如果大就留下來,如果小艳汽,就離開猴贰。
D:最后參照物里面保存的就是最大值。
*/
class ArrayTest2 {
public static void main(String[] args) {
//定義一個數(shù)組
int[] arr = {34,98,10,25,67};
//請獲取數(shù)組中的最大值
/*
//從數(shù)組中任意的找一個元素作為參照物
int max = arr[0];
//然后遍歷其他的元素
for(int x=1; x<arr.length; x++) {
//依次獲取和參照物進行比較河狐,如果大就留下來米绕,如果小瑟捣,就離開。
if(arr[x] > max) {
max = arr[x];
}
}
//最后參照物里面保存的就是最大值栅干。
System.out.println("max:"+max);
*/
//把這個代碼用方法改進
//調用方法
int max = getMax(arr);
System.out.println("max:"+max);
//請獲取數(shù)組中的最小值
int min = getMin(arr);
System.out.println("min:"+min);
}
/*
需求:獲取數(shù)組中的最大值
兩個明確:
返回值類型:int
參數(shù)列表:int[] arr
*/
public static int getMax(int[] arr) {
//從數(shù)組中任意的找一個元素作為參照物
int max = arr[0];
//然后遍歷其他的元素
for(int x=1; x<arr.length; x++) {
//依次獲取和參照物進行比較迈套,如果大就留下來,如果小碱鳞,就離開桑李。
if(arr[x] > max) {
max = arr[x];
}
}
//最后參照物里面保存的就是最大值。
return max;
}
public static int getMin(int[] arr) {
//從數(shù)組中任意的找一個元素作為參照物
int min = arr[0];
//然后遍歷其他的元素
for(int x=1; x<arr.length; x++) {
//依次獲取和參照物進行比較劫笙,如果小就留下來芙扎,如果大,就離開填大。
if(arr[x] < min) {
min = arr[x];
}
}
//最后參照物里面保存的就是最小值戒洼。
return min;
}
}
運行結果:
4.10.3 數(shù)組元素逆序
/*
數(shù)組元素逆序 (就是把元素對調)
分析:
A:定義一個數(shù)組,并進行靜態(tài)初始化允华。
B:思路
把0索引和arr.length-1的數(shù)據(jù)交換
把1索引和arr.length-2的數(shù)據(jù)交換
...
只要做到arr.length/2的時候即可圈浇。
*/
class ArrayTest3 {
public static void main(String[] args) {
//定義一個數(shù)組,并進行靜態(tài)初始化靴寂。
int[] arr = {12,98,50,34,76};
//逆序前
System.out.println("逆序前:");
printArray(arr);
//逆序后
System.out.println("逆序后:");
//reverse(arr);
reverse2(arr);
printArray(arr);
}
/*
需求:數(shù)組逆序
兩個明確:
返回值類型:void (有人會想到應該返回的是逆序后的數(shù)組磷蜀,但是沒必要,因為這兩個數(shù)組其實是同一個數(shù)組)
參數(shù)列表:int[] arr
*/
public static void reverse(int[] arr) {
/*
//第一次交換
int temp = arr[0];
arr[0] = arr[arr.length-1-0];
arr[arr.length-1-0] = temp;
//第二次交換
int temp = arr[1];
arr[1] = arr[arr.length-1-1];
arr[arr.length-1-1] = temp;
//第三次交換
int temp = arr[2];
arr[2] = arr[arr.length-1-2];
arr[arr.length-1-2] = temp;
*/
//用循環(huán)改進
for(int x=0; x<arr.length/2; x++) {
int temp = arr[x];
arr[x] = arr[arr.length-1-x];
arr[arr.length-1-x] = temp;
}
}
public static void reverse2(int[] arr) {
for(int start=0,end=arr.length-1; start<=end; start++,end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
}
//遍歷數(shù)組
public static void printArray(int[] arr) {
System.out.print("[");
for(int x=0; x<arr.length; x++) {
if(x == arr.length-1) { //這是最后一個元素
System.out.println(arr[x]+"]");
}else {
System.out.print(arr[x]+", ");
}
}
}
}
運行結果:
4.10.4 數(shù)組基本查找
/*
需求:數(shù)組元素查找(查找指定元素第一次在數(shù)組中出現(xiàn)的索引)
分析:
A:定義一個數(shù)組百炬,并靜態(tài)初始化褐隆。
B:寫一個功能實現(xiàn)
遍歷數(shù)組,依次獲取數(shù)組中的每一個元素剖踊,和已知的數(shù)據(jù)進行比較
如果相等庶弃,就返回當前的索引值。
*/
class ArrayTest5 {
public static void main(String[] args) {
//定義一個數(shù)組德澈,并靜態(tài)初始化
int[] arr = {200,250,38,888,444};
//需求:我要查找250在這個數(shù)組中第一次出現(xiàn)的索引
int index = getIndex(arr,250);
System.out.println("250在數(shù)組中第一次出現(xiàn)的索引是:"+index);
int index2 = getIndex2(arr,250);
System.out.println("250在數(shù)組中第一次出現(xiàn)的索引是:"+index2);
int index3 = getIndex2(arr,2500);
System.out.println("2500在數(shù)組中第一次出現(xiàn)的索引是:"+index3);
}
/*
需求:查找指定數(shù)據(jù)在數(shù)組中第一次出現(xiàn)的索引
兩個明確:
返回值類型:int
參數(shù)列表:int[] arr,int value
*/
public static int getIndex(int[] arr,int value) {
//遍歷數(shù)組歇攻,依次獲取數(shù)組中的每一個元素,和已知的數(shù)據(jù)進行比較
for(int x=0; x<arr.length; x++) {
if(arr[x] == value) {
//如果相等梆造,就返回當前的索引值缴守。
return x;
}
}
//目前的代碼有一個小問題
//就是假如我要查找的數(shù)據(jù)在數(shù)組中不存在,那就找不到镇辉,找不到屡穗,你就對應的返回嗎?
//所以報錯。
//只要是判斷忽肛,就可能是false鸡捐,所以大家要細心。
//如果找不到數(shù)據(jù)麻裁,我們一般返回一個負數(shù)即可,而且是返回-1
return -1;
}
public static int getIndex2(int[] arr,int value) {
//定義一個索引
int index = -1;
//有就修改索引值
for(int x=0; x<arr.length; x++) {
if(arr[x] == value) {
index = x;
break;
}
}
//返回index
return index;
}
}
運行結果: