文末有Gitee鏈接,記得star哦 課程整體內容概述 第一部分:編程語言核心結構 主要知識點:變數、基本語法、分支、迴圈、數組、 第二部分:Java面向對象的核心邏輯 主要知識點:OOP、封裝、繼承、多態、介面、 第三部分:開發JavaSE高級應用程式 主要知識點:異常、集合、|℃、多線程、反射機 ...
文末有Gitee鏈接,記得star哦
課程整體內容概述
第一部分:編程語言核心結構
主要知識點:變數、基本語法、分支、迴圈、數組、
第二部分:Java面向對象的核心邏輯
主要知識點:OOP、封裝、繼承、多態、介面、
第三部分:開發JavaSE高級應用程式
主要知識點:異常、集合、|℃、多線程、反射機制、網路編程、
第四部分:實訓項目
項目一:家庭收支記賬軟體
項目二:客戶信息管理軟體
項目三:開發團隊人員調度軟體
附加項目一:銀行業務管理軟體
附件項目二:單機考試管理軟體
項目一:講完流程式控制制時,可以做。第二章結束
項目二:講完面向對象(上)。即第四章
項目三:講完異常處理,即第七章
附加項目一:講完異常處理,即第七章
附加項目二:講完IO流以後,即第11章
Java語言概述
1 基礎常識
軟體:即一系列按照特定順序組織的電腦數據和指令的集合。分為:系統軟體和應用軟體。
系統軟體:Windows,Linux,macOS,Android,Unix,ios
應用軟體:word,ppt,畫圖板.....
人機交互方式:圖形化界面 vs 命令行方式
應用程式 = 演算法 + 數據結構
①常用DOS命令
dir:列出當前目錄下的文件以及文件夾
md:創建目錄
rd:刪除目錄
cd:進入指定目錄cd.. :退回到上一級目錄
cd\:退回到根目錄
del:刪除文件
exit:退出dos命令行
補充:echOjavase > 1.doc
常用快捷鍵:
←→:移動游標
↑ ↓:調閱歷史操作命令
DeIete和Backspace:刪除字元
2 電腦語言的發展迭代史
第一代:機器語言
第二代:彙編語言
第三代:高級語言
面向過程:C
面向對象:Java,JS,Python
3 Java語言版本迭代概述
1991年Green項目,開發語言最初命名為Oak(橡樹)
1994年,開發組意識到Oak非常適合於互聯網
1996年,發佈JDK1.0,約8.3萬個網頁應用Java技術來製作
1997年,發佈JDK1.1,JavaOne會議召開,創當時全球同類會議規模之最
1998年,發佈JDK1.2,同年發佈企業平臺J2EE
1999年,Java分成J2SE、J2EE和J2ME,JSP/ServIet技術誕生
2004年,發佈里程碑式版本:JDK1.5,為突出此版本的重要性,更名為JDK5
2005年,J2SE->JavaSE,J2EE->JavaEE,J2ME->JavaME
2009年,Oracle公司收購SUN,交易價格74億美元
2011年,發佈JDK7.0
2014年,發佈JDK8.0,是繼JDK5.0以來變化最大的版本
2017年,發佈JDK9.0,最大限度實現模塊化
2018年3月,發佈JDK10.0,版本號也稱為18.3
2018年9月,發佈JDK11.0,版本號也稱為18.9
4 Java語言應用的領域:
Java Web開發:後臺開發
大數據開發
Android應用程式開發:客戶端開發
5 Java語言的特點
面向對象性
兩個要素:類、對象
三個特征:封裝、繼承、多態
健壯性:(1)取除了C語言的指針
(2)自動垃圾回收機制(仍然會出現記憶體溢出、記憶體泄漏)
(3)跨平臺性:write once ,run anywhere:一次編譯,到處運行(基於JVM實現)
開發環境搭建
1 JDK、JRE、JVM的關係
2 JDK的下載、安裝
下載:官網
安裝:一直下一步傻瓜式安裝(安裝路線不能包含中文、空格)****
3 path環境變數的配置
-
為什麼配置path環境變數?
path環境變數:windows操作系統執行命令時要搜尋的路徑
為了再任意文件路徑下可以運行Java的開發工具(javac.exe java.exe) -
如何配置?
第一個Java程式
1 開發體驗--HelloWorld
2 編寫
創建一個java源文件:HelloWorld
class HelloWorld{
public static void main(String[] args){
System.out.println("Hello,World");
}
}
3 編譯
javac HelloWorld
4 運行
java HelloWorld
5 總結第一個程式
在一個java源文件中可以有多個類,但只能有一個類被public修飾,並且public修飾的類的類名必須與文件名一致
程式的入口是main,main方法的格式是固定的。
每個執行語句都要以;(分號)結尾
註釋與API文檔等
1 註釋
分類:
單行註釋//
多行註釋/**/
文檔註釋/** */
作用:
對代碼進行解釋說明
特點:
註釋內容可以被JDK提供的工具javadoc所解析,生成一套以網頁形式的該程式的說明文檔。
多行註釋不能嵌套使用
2 Java API文檔
語言提供的類庫成為API
API文檔:對提供的類庫如何使用給的一個說明書,也可以說是字典
3 良好的編程風格
常用的開發工具
1 文本編輯工具
- 記事本
- UltraEdit
- EditPlus(常用)
- TextPad
- NotePad(常用)
2 Java集成開發環境(IDE)
- Jbuilder
- NetBeans
- Eclipse(常用)
- MyEclipse
- IntelliJ IDEA(常用)
關鍵字與標識符
1 Java關鍵字的使用
定義:被Java賦予特殊意義,用作專門用途的字元串(單詞)
特點:所有字母都是小寫的
具體哪些關鍵字:
2 保留字
現Java版本尚未使用,但以後版本可能會作為關鍵字使用的。
具體哪些保留字:goto、const
註意:自己命名標識符時要避免使用這些保留字
3 標識符的使用
定義:需要自己起名字的地方都叫做標識符
涉及到的結構:
包名、類名、介面名、方法名、變數名、常量名
規則:(必須要遵守。否則,編譯不通過)
由26個英文字母大小寫,0-9 ,_或 $ 組成
數字不可以開頭。
不可以使用關鍵字和保留字,但能包含關鍵字和保留字。
Java中嚴格區分大小寫,長度無限制。
標識符不能包含空格。
規範:(可以不遵守,不影響編譯和運行。但是要求大家遵守)
包名:多單片語成時所有字母都小寫:xxxyyyzzz
類名、介面名:多單片語成時,所有單詞的首字母大寫:XxxYyyZzz
變數名、方法名:多單片語成時,第一個單詞首字母小寫,第二個單詞開始每個 單詞首字母大寫:xxxYyyZzz
常量名:所有字母都大寫。多單詞時每個單詞用下劃線連接:XXX_YYY_ZZZ
註意點: 見名知意
變數的使用 (重點)
1 變數的分類
1.1按數據類型分
詳細說明:
整型:byte(一位元組)、short(2位元組)、int(4位元組)、long(8位元組)
①byte範圍(-128-127)
②聲明long變數時,必須以l或L結尾
③一般定義整型變數時,使用int型
④整型的常量,預設類型為:int型
浮點型:float(4位元組)、double(8位元組)
①浮點型,表示帶小數點的數值
②float的範圍比int還大
③聲明float變數時,必須以f或F結尾
④定義浮點型變數時,一般使用double型
⑤浮點型的常量,預設類型為:double型
字元:char(1字元=2位元組)
①定義char變數時,需要用一對''包裹,並且只能含有一個字元
②表示方式:1.聲明一個字元 2.轉義字元 3.直接使用Unicode值來表示字元型常量
布爾型:boolean
①只有兩個值:true、false
②常常在條件判斷、迴圈結構語句中使用
- 按聲明的位置分類(瞭解)
2 定義變數的格式
①數據類似 變數名 = 變數值;
②數據類型 變數名;
變數名 = 變數值;
3 變數使用的註意點
①變數必須先聲明,後使用
②變數都定義在其作用域內。在作用域內,它是有效的
③同一個作用域內,不能聲明兩個同名變數
4 基本數據類型變數間運算規則
4.1 涉及到的基本數據類型:
byte、short、char、 int 、 long 、 float 、double
4.2 自動類型轉換(只涉及7種基本數據類型)
byte,short,char --> int --> long --> float --> double
結論:當容量小的數據類型的變數與容量大的數據類型做運算時,結果會自動轉換為容量大的數據類型
特別的:當byte、char、short三者相互或自己做運算時都會轉換為int型
註:容量大小指的是,表示數的範圍的大小。而不是位元組大小。比如float容量要大於long
4.3 強制類型轉換(只涉及7種基本數據類型)
自動類型轉換的逆運算
①需要強轉符()
②強制類型轉換會出現精度損失
4.4 String與8種基本數據類型間的運算
①String屬於引用型數據類型,理解為:字元串
②聲明String類型變數時,需要用一對""包裹。
③String可以和8種基本數據類型做運算,且運算只能是連接運算:+
④運算的結果仍為String類型
避免:
String s = 123;//編譯錯誤
String s1 = "123";
String s2 = (int) s1;//編譯錯誤
運算符
1 算術運算符 +(正) -(負) + - (前)++ (後)++ (前)-- (後)-- * / % +(連接符)
1.1 典型代碼:
//除號: /
int num1 = 12;
int num2 = 5;
int num3 = num1 / num2;
System.out.println(num3);//結果num3 = 2;
//取餘 :%
結果的符號與被模數的符號相同
開發中,通常使用%來實現能否被除盡
int y1 = 14;
int y2 = 3;
int y = y1 % y2;
System.out.println(y);//結果y = 2;
//註意點:
short s1 = 2;
//s1 = s1 + 1;//編譯失敗
//s1 = (short)(s1 + 1);//編譯成功
s1++;//自增1不會改變本身的數據類型
System.out.println("s1 = " + s1);
//問題:此時 bb1 等於多少?
byte bb1 = 127;
bb1++;
System.out.println("bb1 = " + bb1);//bb1 = -128
1.2 特殊說明的
①:(前)++:先自增1;後運算
(後)++:先運算;後自增1②:(前)--:先自減1;後運算
(後)--:先運算;後自減1③連接符: + 只能用於String類型與其他數據類型之間使用。
2 賦值運算符 = += -= *= /= %=
2.1 典型代碼:
//賦值符號: =
int i1 = 10;
boolean bl = true;
//連續賦值
int i2,i3;
i2 = i3 = i1;
int j1 = 10,j2 = 20;
int num = 100;
num += 2;
System.out.println(num);
short s1 = 100;
//s1 = s1 + 2;//編譯不通過
s1 += 2;//不會改變變數本身的數據類型
System.out.println(s1);
2.2 特殊說明的
①結果不會改變變數本身的數據類型
②實現變數+2的操作,有幾種方法?(前提是int num = 10;)
方式一:num = num + 2;
方式二:num += 2;//推薦
③實現變數+1的操作,有幾種方法?(前提是int num = 10;)
方式一:num = num + 1;
方式二:num += 1;//推薦
方式三:num++;//推薦
3 比較運算符 == <= >= > < instanceof
3.1 典型代碼:
int i = 10;
int j = 20;
System.out.println(i == j);
System.out.println(i = j);
boolean b1 = true;
boolean b2 = false;
System.out.println(b1 == b2);
System.out.println(b1 = b2);
3.2 特殊說明的
1.比較運算符的結果都是boolean類型的
2.區分 == 和 =3.<= >= > < :只能使用在數值類型的數據之間
4.==:不僅可以使用在數值類型的數據之間,還可以使用在引用型變數之間 Account acct1 = new Account(1000);
Account acct1 = new Account(2000); boolean b1 == (acct1 == acct2); //比較兩個Account是否是同一個賬戶(或者說是否為同一個對象)
boolean b2 == (acct1 != acct2);
4 邏輯運算符 &(與) && |(或) || ! ^
4.1 典型代碼:
boolean b1 = true;
b1 = false;
int num1 = 10;
// & 與 &&
if(b1 & num1 == 10){
System.out.println("我要吃冰淇淋!");
}else{
System.out.pritln("我要吃喜之郎!")
}
if(b1 && num1 == 10){
System.out.println("我要吃冰淇淋!");
}else{
System.out.pritln("我要吃喜之郎!")
}
// | 與 ||
if(b1 | num1 == 10){
System.out.println("我要吃冰淇淋!");
}else{
System.out.pritln("我要吃喜之郎!")
}
if(b1 || num1 == 10){
System.out.println("我要吃冰淇淋!");
}else{
System.out.pritln("我要吃喜之郎!")
}
4.2 特殊說明的
1.邏輯運算符運算的也都是boolean類型的變數,結果也是boolean類型的
2.開發中推薦使用 &&
3.開發中推薦使用 ||
4.3 區分& 與 &&
相同點:
1.& 和 && 運算結果都一樣
2.符號左邊是true時,兩者都會執行符號右邊的運算
不同點:1.符號左邊是false時,&會執行符號右邊的運算,而 && 不會執行符號右邊的運算
4.4 區分 | 與 ||
相同點:
1.| 和 || 運算結果都一樣
2.符號左邊是false時,兩者都會執行符號右邊的運算
不同點: 1.符號左邊是true時,| 會繼續執行符號右邊的運算,而 || 不會執行符號右邊的運算
5 位運算符(瞭解就行) << >> >>> & | ^ ~(取反)
5.1 典型代碼:(面試題) 你能否寫出最高效的2 * 8的實現方式?
答案:2 << 3 8 << 1
5.2 特殊說明的
1.位運算符操作的都是整型的數據
2.<< :在一定範圍內,每向左移1位,相當於 * 2
3.>> :在一定範圍內,每向右移1位,相當於 / 2
6 三元運算符 (條件表達式) ? 表達式1 : 表達式2
6.1 典型代碼:
//獲取兩個整數的較大值
int m = 10;
int n = 5;
int max = (m > n) ? m : n;
System.out.println(max);
//獲取三個整數的較大值
int num1 = 10;
int num2 = 29;
int num3 = 3;
//不建議
int max3 = (((num1>num2)? num1:num2)>num3)?((num1>num2)?num1 : num2):num3;
System.out.println(max3);
6.2 特殊說明的
①條件表達式的結果為boolean型
②根據條件表達式的真或假,決定執行表達式1,還是執行表達式2
如果為true,則執行表達式1
如果為false,則執行表達式2
③表達式1和表達式2要求是一致的
④三元運算符是可以嵌套的
⑤凡是可以使用三元運算符的地方都可以改寫成if-else結構,使用if-else的不一定能改成三元運算符。反之,不成立。
⑥如果程式既可以使用三元運算符又可以使用if-else,那麼優先使用三元運算符
原因:簡潔、執行效率高
流程式控制制
①順序控制:程式從上到下執行
②分支結構:if-else、switch-case
③迴圈結構:for迴圈、while迴圈、do-while迴圈
1 補充Scanner的使用
import java.util.Scanner
Scanner sc = new Scanner(System.in);
int i1 = sc.nextInt();
2 分支結構
2.1 if-else條件判斷結構
2.1.1 結構:
①
if(條件表達式){
執行表達式
}
②二選一
if(條件表達式){
執行表達式1
}else{
執行表達式2
}
③多選一(n選一)
if(條件表達式){
執行表達式1
}else if{
執行表達式2
}else if{
執行表達式3
}
...
else{
執行表達式n
}
2.1.2說明:
1.if-else是可以嵌套使用的
2.else是可選的
3.if-else結構中的執行語句只有一行時;對應的{}可以省略;But一般不省略
2.2 switch-case選擇結構
2.2.1 結構:
結構一:
switch(表達式){
case 1:
執行表達式1;
break;
case 2:
執行表達式2;
break;
case 3:
執行表達式3;
break;
default:
執行表達式4;}
結構二:
switch(表達式){
case 1:
case 2:
執行表達式1;
break;
case 3:
case 4:
執行表達式2;
break;
default:
執行表達式3;}
2.2.2 說明:
①.switch-case結構適用於表達式值較少的時候
②.switch-case根據表達式中的值去依次匹配case,匹配成功會進入case執行語句;執行完之後,如果沒有break,那麼會繼續執行下麵的case中的執行語句,知道末尾或者遇到break為止
③.break:可以跳出switch-case結構,break是可選的
④.switch結構中的表達式,只能是以下六種類型:byte、short、char、int、枚舉類型、String數據類型
⑤.default相當於if-else中的else,一樣是可選的,而且位置是靈活的
⑥如果switch-case中有多個case的執行語句相同,那麼可以把case合併在一起
3 迴圈結構
3.1迴圈結構的四要素
①初始化條件
②迴圈條件 (是boolean類型的)
③迴圈體
④迭代條件說明:通常情況下,迴圈結束都是因為②中迴圈條件返回false而結束的
3.2 三種迴圈結構
3.2.1 for迴圈結構
for (①;②;④){
③;
}
執行過程:
①-②-③-④-②-③-④·····②
3.2.2 while迴圈結構
①;
while(②){
③; ④;
}
執行過程:
①-②-③-④-②-③-④·····②
說明:
寫While迴圈一定不要缺少迭代條件,否則會出現死迴圈
for 和 while 總結:
1.執行過程和if-else一樣
2.開發中,基本上都是從for和while兩者之間進行選擇,實現迴圈結構
3.for 和 while 是可以相互轉換的
區別:for迴圈和While迴圈的初始條件的作用域不同
4.寫程式時要避免出現死迴圈
3.2.3 do-while迴圈結構
①;
do{
③;
④;
}
while(②)
執行過程:
①-③-④-②-③-④-②-③-④-····-②
說明:
1.do-while會先運行一遍迴圈體和迭代條件
2.當迴圈執行多次時,do-while和while的結果一樣;
當迴圈只執行一次時,do-while和while的結果不一樣;do-while會多運行一次迴圈體
3.開發中使用for和While更多一些。
3.3 “無限迴圈”結構: while(true){}或for( ; ; )
總結:如何結束一個迴圈結構?
1.遇到break、continue,或迴圈條件為false
3.4 嵌套迴圈
3.4.1 嵌套迴圈:
當一個迴圈結構A聲明在另一個迴圈結構B內部,那麼就構成了嵌套迴圈
(1)內層迴圈:迴圈結構A
(2)外層迴圈:迴圈結構B
3.4.2 說明:
①.內層迴圈遍歷一遍,外層迴圈執行一次
②.如果外層迴圈需要執行m次,內層迴圈要執行n次,那麼內層迴圈一共執行了多少次?(m * n)
③外層迴圈控制行數、內層迴圈控制列數。
3.4.3 典型練習:列印九九乘法表
for(int i=1;i<=9;i++){
for(int j=1;j<=i;j++){
System.out.print(j + "*" + i + "=" +(i*j) + "\t");
}
System.out.println();
}
4 補充:衡量一個功能代碼的優劣:
①正確性
② 可讀性
③健壯性
④高效率和低存儲:時間複雜度、空間複雜度(衡量演算法的好壞)
5 break 和 continue
5.1區分break和continue:
1.相同點:break和continue都是結束迴圈的語句,都是採取就近原則
2.不同點:break是跳出當層迴圈;continue是跳出當次迴圈
5.2 帶標簽的break和continue:
lable:for(int i=1;i <= 10;i++){
for(int j=1;j < 5;j++){
break;//結束j迴圈
break lable;//結束i迴圈
continue;//結束j迴圈的當次迴圈
continue lable;//結束i迴圈的當次迴圈
}
}
數組的概述
1 數組的理解:
數組(Array),是多個相同數據類型按一定順序排列的集合,並使用一個名字命名,並通過標號的方式對這些數據進行統一管理。
2 數組相關的概念
①數組名 ②元素 ③下標(索引) ④數組長度:元素的個數
3 數組的特點
①數組是有序排列的
②數組是是屬於引用型數據類型的變數。數組的元素可以是基本數據類型的變數,也可以是引用數據類型的變數
③創建的數組對象會在記憶體中開闢一整塊連續的空間
④數組長度一旦確定,就不能更改
4 數組的分類
①按照維數:一維數組、二維數組....
②按照類型:基本數據類型元素的數組、引用數據類型與元素的數組
一維數組
1 一維數組的聲明與初始化
1.1 正確的方式:
//聲明和初始化分開
int[] arr;
arr = new int[]{1,2,3,4};
//靜態初始化:數組的初始化和數組元素的賦值同時操作
int[] arr = new int[]{1,2,3};
int[] arr1 = {1,2,3,4};//類型推斷
int arr2[] = new int[]{1,2,3};//[]可以寫在int後面,也可以寫在數組名後面
int arr3[] = {1,2,3};//new int[]可以去掉
//動態初始化:數組的初始化和數組元素的賦值分開操作
int[] arr4 = new int[4];
1.2 錯誤的方式:
int[] arr = new int[5]{1,2,3,4,5};//動態和靜態結合在一起
int[] arr1 = new int[];
int[5] arr2 = new int[5];
2 一維數組元素的引用:通過使用下標的方式來調用數組某個位置的數據
//角標是從0開始的,到length-1結束
int[] arr = new int[]{9,4,5,7};
System.out.print(arr[1]);
String[] names = new String[3];
names[0] = "李飛";
names[1] = "張三";
names[2] = "李四";
3 數組的屬性:length
int[] arr = new int[]{9,4,5,7};
System.out.print(arr.length);//4String[] names = new String[3];
System.out.print(names.length);//3說明:
數組一旦初始化,長度就確定了length
數組一但確定,就不能更改了
4 一維數組的遍歷
int[] arr = new int[]{9,4,5,7};
for(int i = 0;i<arr.length;i++){
System.out.print(arr[i] + " ");
}
5 一維數組元素的預設初始化值
①整型:0
②浮點型:0.0
③char:0 或 ‘/u0000’(列印出來是空白)
④boolean型:false
⑤引用類型:null
6 一維數組的記憶體結構
int[] arr1 = new int[4];
arr1[0] = 10;
arr1[2] = 20;
String[] arr2 = new String[3];
arr2[1] = “憨憨”;
arr2 = new String[5];
二維數組
1 如何理解二維數組?
數組屬於引用數據類型
數組的元素也可以是引用數據類型
若一個一維數組A的元素是由一維數組組成的,那麼一維數組A稱為二維數組由數組組成的數組
外層數組的元素是由另一個數組組成的
2 二維數組的聲明與初始化
2.1 正確的方式:
//聲明
int[][] arr;
//初始化
arr = new int[][]{{3,4,6,7},{5,8},{1,9,10}};
//靜態初始化
int[][] arr1 = new int[][]{{9,4,5,7},{5,6},{6,1,6}};
//動態初始化
int[][] arr2 = new int[4][];
int[][] arr3 = new int[4][5];
//其他正確寫法
int[] arr3[] = new int[4][5];
int arr4[][] = new int[4][5];
int[][] arr5 = new int[4][];
2.2 錯誤的方式:
int[][] arr = new int[][];
int[][] arr1 = new int[][4];
[][]int arr2 = new int[][];
int[][] arr3 = new int[4][3]{{1,1,1},{2,2,2},{3,3,3}};
int[][] arr4 = int[4][3];//沒有寫new
3 如何調用二維數組元素
int[][] arr = new int[][]{{9,4,5,7},{5,6},{7,1,8}};
System.out.print(arr[1][1]);//輸出6
String[][] arr1 = new String[4][];
String[][] arr2 = new String[4][3];
System.out.print(arr1[1]);//輸出null //註意區別
System.out.print(arr2[1]);//輸出地址值
4 二維數組的屬性:length
int[][] arr = new int[][]{{9,4,5,7},{5,6},{7,1,8,6,3}};
System.out.print(arr1.length);//3
System.out.print(arr1[0].length);//4
System.out.print(arr1[1].length);//2
System.out.print(arr1[2].length);//5
5 二維數組的遍歷
int[][] arr = new int[][]{{9,4,5,7},{5,6},{6,1,6}};
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();
}
6 二維數組元素的預設初始化值
規定:二維數組分為外層數組的元素和內層數組的元素
int[][] arr = new int[4][3];
外層元素:arr[0]、arr[1]、arr[2]、arr[3];
內層元素:arr[0][0]、arr[0][1]、arr[0][2].......;
數組元素的預設初始化值:
針對初始化方式一:比如:int[][] arr = new int[4][3];
外層元素的初始化值:地址值
內層元素的初始化值:與一維數組的初始化值相同
針對初始化方式二:比如:int[][] arr = new int[4][];
外層元素的初始化值:null
內層元素的初始化值:不能調用
7 二維數組的記憶體結構
int[][] arr1 = new int[4][];
arr1[1] = new int[]{1,2,3};
arr1[2] = new int[4];
arr1[2][1] = 30
數組的常見演算法
1 數組的創建與元素賦值:
楊輝三角(二維數組)、回形數(二維數組)、6個數(範圍:[1-30],不能重覆)
2 針對於數值型的數組:求最大值、最小值、總和、平均數等。
//求最大值
int max = arr[0];
for(int i = 1;i<arr.length;i++) {
if(max <= arr[i]) {
max = arr[i];
}
}
System.out.println("最大值為:" + max);
//求最大值
int min = arr[0];
for(int i = 1;i<arr.length;i++) {
if(min >= arr[i]) {
min = arr[i];
}
}
System.out.println("最小值為:" + min);
//總和
int sum = 0;
for(int i =-0;i<arr.length;i++) {
sum+=arr[i];
}
System.out.println("總和為:" + sum);
//平均數
int avg = 0;
avg = sum / arr.length;
System.out.println("平均數為:" + avg);
3 數組的賦值與複製
int[] array1,array2;
array1 = new int[]{1,2,3,4};
①賦值
array2 = array1;
如何理解:將array1保存的數組的地址值賦給array2,使得兩個數組指向堆空間中的同一個數組實體。
②複製
array2 = new int[array1.length];
for(int i = 0;i<array1.length;i++) {
array2[i] = array1[i];
}
如何理解:我們通過new的方式,給array2在堆空間中新開闢了數組空間,將array1中的元素值一一賦值到array2的數組中。
4 數組元素的反轉
int[] arr = new int[]{34,5,22,-98,6,-76,0,-3};
//方法一:
for(int i = 0;i < arr.length/2;i++) {
int temp = arr[i];
arr[i] = arr[arr.length-i-1];
arr[arr.length-i-1] = temp;
}
//方法二:
for(int i = 0,j = ar.length - 1;i < j;i++,j--) {
int temp = arr[i];
arr[i] = arrj];
arr[j] = temp;
}
5 數組中指定元素的查找:檢索、搜索
5.1線性查找:
實現思路:通過遍歷的方式,一個一個的數據進行比較、查找
適用性:具有普遍適用性即數據類型沒有要求、也不要求數據有序
5.2二分法查找:
實現思路:每次取中間值,折半的方式進行搜索
適用性:數據需要有序
6 數組的排序演算法:十大內部演算法
- 選擇排序:直接選擇排序、堆排序(知道怎麼實現)
- 交換排序:冒泡排序、快速排序(要掌握)
- 插入排序:直接插入排序、折半插入排序、Shell排序
- 歸併排序(知道怎麼實現)
- 桶式排序
- 基數排序
6.1 衡量排序演算法的優劣:
時間複雜度、空間複雜度、穩定性
6.2 排序的分類:內部排序 與 外部排序
1.內部排序:整個排序過程不需要藉助於外部存儲器(如磁碟等),所有排序操作都在記憶體中完成。
2.外部排序:參與排序的數據非常多,數據量非常大,電腦無法把整個排 序過程放在記憶體中完成,必須藉助於外部存儲器(如磁碟)。外部排序最 常見的是多路歸併排序。可以認為外部排序是由多次內部排序組成。
6.3 不同排序演算法的時間複雜度
冒泡排序的時間複雜度:O(n^2)
快速排序的時間複雜度:O(nlogn)
7 冒泡排序的實現:--需要能手寫出來
public class BubbleSortTest {
public static void main(String[] args) {
int[] arr = new int[]{34,5,22,-98,6,-76,0,-3};
//排序
for(int i = 0;i < arr.length - 1;i++) {
for(int j = 0;j < arr.length - i -1 ;j++) {
if(arr[j] >= arr[j+1]) {
int temp;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
//遍歷輸出數組
for(int i = 0;i<arr.length;i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
Arrays工具類的使用
1 理解:
①定義在java.util包下
②Arrays:提供了很多操作數組的方法
2 使用:
//1.boolean.equals(int[] a;int[] b);
//2.輸出數組
Arrays.toString(arr);
//3.void fill(int[] a,val):將指定值填充到數組中
//4.void sort(int[] a)
//5.int binarySearch(int[] a,int key)//二分法查找
數組的常見異常:
一但程式出現異常,並且未處理,那麼將會終止執行
1 數組角標越界異常:ArrayIndexOutOfBoundsException
System.out.println(arr[-2]);
2 空指針異常:NullPointerException
//情況一
int[] arr1 = new int[]{1,2,3}
arr1 = null;
System.out.println(arr1[0]);
//情況二
int[][] arr2 = new int[4][];
System.out.println(arr2[0][0]);
類與對象
1 面向對象的三條主線:
1)類與類的成員:屬性、方法、構造器、代碼塊、內部類
2)面向對象的三大特征:封裝、繼承、多態
3)其他關鍵字:this、super、abstract、interface、static、final、package、import
2 面向對象與面向過程:
1)面向過程:強調的功能行為,以函數為最小單位,考慮怎麼做。
2)面向對象:強調具備了功能的對象,以類/對象為最小單位,考慮誰來做
對比舉例:把大象放進冰箱。
3 完成一個項目(或功能)的思想:
1)根據問題需要,選擇問題所針對的現實世界中的實體。
2)從實體中尋找解決問題相關的屬性和功能,這些屬性和功能就形成了概念世界中的類。
3) 把抽象的實體用電腦語言進行描述,形成電腦世界中類的定義。即藉助某種程式 語言,把類構造成電腦能夠識別和處理的數據結構。
4)將類實例化成電腦世界中的對象。對象是電腦世界中解決問題的最終工具。
4 面向對象的兩個重要概念:類和對象
1)類:對一類實物的描述,抽象的、概念上的內容
對象:是實際存在的該類事物的每個個體,因而也成為實例(instance)
2)面向對象程式設計的重點就是類的設計
設計類、就是設計類的成員。3)類是對象的抽象
對象是有類new出來的,派生出來的
5 面向對象思想落地實現的規則
1)創建類,設計類的成員
2)創建類的對象
3)通過"對象.屬性"或"對象.方法"調用對象的結構
6 補充:幾個概念的使用說明
屬性 = 成員變數 = field = 域、欄位
方法 = 成員方法 = method = 函數
創建類的對象 = 類的實例化 = 實例化類
7 對象的創建與對象的記憶體解析
7.1 典型代碼:
Person p1 = new Perosn();
Person p2 = new Perosn();
Person p3 = p1;//沒有新建一個對象,共用一個堆空間中的實體對象
7.2 說明:
如果創建了一個類的多個對象,則每個對象都獨立的擁有一套類的屬性。(非static的)
意味著:如果我們修改一個對象的屬性,另一個對象的屬性不會改變
7.3 記憶體解析
8 匿名對象:
我們創建的對象,沒有顯式的賦給一個變數名。即為匿名對象
8.1 特點:
匿名對象只能調用一次。
8.2 舉例:
new Student().屬性 或 new Student().方法
new Phone().sendEmail();
new Phone().playGamel();
new Phone().price = 1999;
new Phone().showPrcie = 1999;
8.3 應用場景:
PhoneMall mall = new PhoneMall();
//匿名對象的使用
mall.show(new Phone());
class PhoneMall{
public void show (Phone phone){
phone.sendEmail();
phone.playGame();
}
}
9 理解"萬事萬物皆對象"
1.在Java語言範疇中,我們都將功能、結構等封裝到類中,通過類的實例化,來調用具體的功能結構
Scanner,String等、文件:File、網路資源:URL
2.涉及到Java語言與前端Html、後端的資料庫交互時,前後端的結構在Java層面交互時,都體現為類、對象。
10 JVM的記憶體結構
編譯完源程式以後,生成一個或多個位元組碼文件。
我們使用JVM中的類的載入器和解釋器對生成的位元組碼文件進行解釋運行。意味著:需要將位元組碼文件對應的類載入到記憶體中,涉及到記憶體解析。
虛擬機棧,即為平時說的棧結構。我們平時把局部變數存儲在棧結構中
堆,我們把new出來的結構(數組、對象等)載入到堆空間中。補充:對象的屬性(非static的)載入到堆空間中。
方法區:類的載入信息、常量池、靜態域
類的結構之一:屬性
類的設計中,兩個重要結構之一:屬性
屬性 = 成員變數 = filed = 域、欄位
1 對比:屬性 vs 局部變數
1.1 相同點:
①定義變數的格式:數據類型 變數名 = 變數值;
②先聲明,後使用
③變數都有其對應的作用域
1.2 不同點:
①在類中聲明的位置不同:屬性直接定義在類的一對{}中;局部變數定義在方法內、方法形參、構造器形參、構造器內部的變數
②關於許可權修飾符的不同:屬性:可以在聲明時,指明其許可權,使用許可權修飾符。常用的許可權修飾符:public 、private、預設、protected。局部變數不可以使用許可權修飾符。
③預設初始值:屬性:類的屬性根據其類型都有預設初始化值:整型:0、浮點型:0.0、char:0或('\u0000')、boolean型:false、引用類型(類、介面、數組):null。局部變數:沒有初始化值,故在使用前必須賦值,形參在調用時賦值即可。
④在記憶體中的位置不同:屬性:載入在堆空間中;局部變數:載入在棧空間中
1.3 補充:回顧變數的分類
方式一:按照數據類型:
①基礎數據類型:byte、short、char、int、long、float、double、boolean
②引用數據類型:類、介面、數組
方式二:按照類中聲明的位置:
①成員變數:實例變數(不以static修飾)、類變數(以static修飾)
②局部變數:形參(方法、構造器中定義的變數)、方法局部變數(在方法內定義)、代碼塊局部變數(在代碼塊內定義)
類的結構之二:方法
方法:描述類應該具有的功能。
比如:Math類:sqrt()\random() \...
Scanner類:nextXxx() ...
Arrays類:sort() \ binarySearch() \ toString() \ equals() \ ...
1 舉例:
public void eat(){}
public void sleep(int hour){}
public String getName(){}
public String getNation(String nation){}
2 方法的聲明:
許可權修飾符 返回值類型 方法名(形參列表){
方法體
}
註意:static、final、abstract 來修飾的方法,後面再講。
3 說明:
3.1 關於許可權修飾符:
預設方法的許可權修飾符先都使用public
Java規定的4種許可權修飾符:private、public、預設、protected -->封裝性再細說
3.2 返回值類型:
3.2.1 有返回值 vs 沒有返回值
① 如果方法有返回值,則必須在方法聲明時,指定返回值的類型。同時,方法中,需要使用
return關鍵字來返回指定類型的變數或常量:“return 數據”
②如果方法沒有返回值,則方法聲明時,使用void來表示。通常,沒有返回值的方法中,就不需要
使用return.但是,如果使用的話,只能“return;”表示結束此方法的意思。
3.2.2我們定義方法該不該有返回值?
① 題目要求
② 憑經驗:具體問題具體分析
3.3 方法名:
屬於標識符,遵循標識符的規則和規範,“見名知意”
3.4 形參列表:
方法可以聲明0個,1個,或多個形參。
1)格式:數據類型1 形參1,數據類型2 形參2,...
2)我們定義方法時,該不該定義形參?
① 題目要求
② 憑經驗:具體問題具體分析
3.5 方法體:
方法功能的體現。
類的設計中,兩個重要結構之二:方法
方法 = 成員方法 = method = 函數
3.6方法的使用:
在使用中可以調用當前類或方法
特殊地:方法A中可以調用方法A:稱為遞歸調用
註意:方法中不可以調用方法。
4 關鍵字:return :
① 適用範圍:方法體內
② 作用:
1)結束方法體
2)如果方法有返回值,那麼可以使用return去返回值
③ 註意點:return後面不能有執行語句
5 方法的重載
5.1 方法的重載的概念
在同一個類中,允許存在一個以上的同名方法,只要它們的參個數或者參類型不同即可。
"兩同一不同":同一個類、相同方法名
參數列表不同:參數個不同,參類型不同
5.2 構成重載的舉例和不構成重載的舉例
Arrays類中重載的sort() / binarySearch();Printstream中的println()
//1-4構成了重載
public void getSum(double d1,double d2) {
System.out.println("1");
}
public void getSum(int m,int n) {
System.out.println("2");
}
public void getSum(String str) {
System.out.println("3");
}
public void getSum(String str,String str1) {
System.out.println("4");
}
//1-5不構成了重載
// public double getSum(double d1,double d2) {
// System.out.println("5");
// return d1;
// }
//2-6-7不構成了重載
// public int getSum(int m,int n) {
// System.out.println("6");
// return 0;
// }
// public int getSum(int i,int j) {
// System.out.println("7");
// return 0;
//}
5.3 如何判斷是否構成重載
根據定義:方法名是否相同;是否在同一個類中;參數列表是否相同
跟方法的許可權修飾符、返回值類型、形參變數名、方法體都沒有關係!
5.4 如何確定類中某一個方法的調用:
在通過對象調用方法時,如何確定調用的是哪一個方法:
方法名 ---> 參數列表
6 可變個數形參的方法
6.1 使用說明:
可變個數形參的方法
1.jdk 5.0新增的內容
2.具體使用:
2.1可變個數形參的格式:數據類型 ... 變數名
2.2當調用可變個數形參的方法時,傳入的參數個數可以是:0個,1個,2個。。。。
2.3可變個數形參的方法與本類中方法名相同、形參不同的方法之間構成重載
2.4可變個數形參的方法與本類中方法名相同、形參類型也相同的數組之間不構成重載。換句話說,二者不能共存。
2.5可變個數形參在方法的形參中,必須聲明在末尾
2.6可變個數形參在方法的形參中,最多只能聲明一個可變形參。
6.2 舉例說明:
public class MethodArgsTest {
public static void main(String[] args) {
MethodArgsTest test = new MethodArgsTest();
test.method("hello");
test.method("hi","china");
test.method("hello","world","!!!");
}
public void method(String str) {
System.out.println("一個參數");
}
public void method(String str1,String str2) {
System.out.println("兩個參數");
}
public void method(String ... str1) {
System.out.println("可變參數");
}
}
7 Java的值傳遞機制
7.1 針對於方法內變數的賦值舉例:
規則:
如果變數是基本數據類型,此時貝武值的是變數所保存的數據值。
如果變數是引用數據類型,此時贓值的是變數所保存的數據的她址值。
7.2 針對於方法的參數概念
形參:方法定義時,聲明的小括弧內的參數。
實參:方法調用時,實際傳遞給形參的數據
7.3 java中參數傳遞機制:值傳遞機制
規則:
如果參數是基本數據類型,此時實參賦給形參的是實參真實存儲的數據值。
如果變數是引用數據類型,此時賦值的是變數所保存的數據的地址值。
7.4 典型例題與記憶體解析:
8 遞歸方法
8.1.定義:
遞歸方法:一個方法體內調用自己
8.2 如何理解遞歸方法?
1.遞歸方去一個方法體內調用它自身。
2.方法遞歸包含了一種隱式的迴圈,它會重覆執行某段代碼,但這種重覆執行無須迴圈控制。
遞歸一定要向已知方向遞歸,否則這種遞歸就變成了無窮遞歸,類似於死迴圈。
8.3 舉例:
// 計算1-n之間所有的自然數的和
public int getSum(int n) {
if (n == 1) {
return 1;
} else {
return n + getSum(n - 1);
}
}
// 計算1-n之間所有的自然數的乘積
public int getMul(int n) {
if (n == 1) {
return 1;
} else {
return n * getMul(n - 1);
}
}
9 突發奇想
9.1 屬性個方法名可不可以相同:(可以)
int age;
public static void main(String[] args) {
MethodArgsTest m = new MethodArgsTest();
m.age = 10;
m.age();
}
public void age() {
System.out.println(age);
}
面向對象的特征一:封裝性
1.為什麼要引入封裝性?
1.我們程式設計追求“高內聚,低耦合”。
①高內聚 :類的內部數據操作細節自己完成,不允許外部干涉;
②低耦合 :僅對外暴露少量的方法用於使用。
2.隱藏對象內部的複雜性,只對外公開簡單的介面。便於外界調用,從而提 高系統的可擴展性、可維護性。通俗的說,把該隱藏的隱藏起來,該暴露的暴露出來。這就是封裝性的設計思想。
2.問題引入:
當我們創建一個類的對象以後,我們可以通過"對象.屬性"的方式,對對象的屬性進行賦值。這裡,賦值操作要受到屬性的數據類型和存儲範圍的制約。除此之外,沒有其他制約條件。但是,在實際問題中,我們往往需要給屬性賦值加入額外的限制條件。這個條件就不能在屬性聲明時體現,我們只能通過方法進行限制條件的添加。(比如:setLegs())同時,我們需要避免用戶再使用"對象.屬性"的方式對屬性進行賦值。則需要將屬性聲明為私有的(private).
-->此時,針對於屬性就體現了封裝性。
3.封裝性思想具體的代碼體現:
體現一:將類的屬性xxx私有化(private),同時,提供公共的(public)方法來獲取(getXxx)和設置(setXxx)此屬性的值
private double radius; //私有屬性
//set方法
public void setRadius(int radius) {
this.radius = radius;
}
//get方法
public double getRadius() {
return radius;
}
體現二:不對外暴露的私有的方法
體現三:單例模式(將構造器私有化)
體現四:如果不希望類在包外被調用,可以將類設置為預設的
4.Java規定的四種許可權修飾符
4.1 許可權從小到大順序為:
private --> 預設 --> protected --> public
4.2 具體的修飾範圍:
private:當前類
預設:當前類、當前包
protected:當前類、當前包、不同包下打的子類
public:當前類、當前包、不同包下打的子類、同項目下的包
4.3 許可權修飾符可用來修飾的結構說明:
屬性、方法、構造器、內部類
修飾類的話能使用兩種:public、預設
類的結構之三:構造器
1 構造器(或構造方法):Constructor
1.1 構造器的作用:
①創建對象 ②初始化對象的信息
2 使用說明:
①如果沒有顯式的定義類的構造器的話,則系統預設提供一個空參的構造器
②定義構造器的格式:許可權修飾符 類名(形參列表){}
③一個類中定義的多個構造器,彼此構成重載
④一旦我們顯式的定義了類的構造器之後,系統就不再提供預設的空參構造器
⑤一個類中,至少會有一個構造器。
3 舉例:
//構造器
public Person(){
System.out.println("Person().....");
}
public Person(String n){
name = n;
}
public Person(String n,int a){
name = n;
age = a;
}
4 屬性賦值的順序
① 預設初始化
② 顯式初始化
③ 構造器中初始化
上面表示對象初始化的時候,下麵表示初始化後續的操作
④ 通過"對象.方法" 或 "對象.屬性"的方式,賦值以上操作的先後順序:① - ② - ③ - ④
5 JavaBean的概念
JavaBean是一種Java語言寫成的可重用組件。
所謂JavaBean,是指符合如下標準的Java類:
①類是公共的
②有一個無參的公共的構造器
③有屬性,且有對應的get、set方法
關鍵字:this
1 可以調用的結構:
屬性、方法;構造器
2 this調用屬性、方法:
①this理解為:當前對象 或 當前正在創建的對象
②在類的方法中,我們可以使用"this.屬性"或"this.方法"的方式,調用當前對象屬性或方法。但是,通常情況下,我們都選擇省略"this."。特殊情況下,如果方法的形參和類的屬性同名時,我們必須顯式的使用"this.變數"的方式,表明此變數是屬性,而非形參。
③在類的構造器中,我們可以使用"this.屬性"或"this.方法"的方式,調用當前正在創建的對象屬性或方法。但是,通常情況下,我們都選擇省略"this."。特殊情況下,如果構造器的形參和類的屬性同名時,我們必須顯式的使用"this.變數"的方式,表明此變數是屬性,而非形參。
3 this調用構造器:
① 我們在類的構造器中,可以顯式的使用"this(形參列表)"方式,調用本類中指定的其他構造器
② 構造器中不能通過"this(形參列表)"方式調用自己
③ 如果一個類中有n個構造器,則最多有 n - 1構造器中使用了"this(形參列表)"
④ 規定:"this(形參列表)"必須聲明在當前構造器的首行
⑤ 構造器內部,最多只能聲明一個"this(形參列表)",用來調用其他的構造器
關鍵字:package/import
1 package的使用
1.1 使用說明:
1.為了更好的實現項目中類的管理,提供包的概念
2.使用package聲明類或介面所屬的包,聲明在源文件的首行
3.包,屬於標識符,遵循標識符的命名規則、規範(xxxyyyzzz)、“見名知意”
4.每"."一次,就代表一層文件目錄。
補充:同一個包下,不能命名同名的介面、類。
不同的包下,可以命名同名的介面、類。
1.2 舉例:
①某航運軟體系統包括:一組域對象、GUI和reports子系統
②MVC設計模式
1.3 JDK中的主要包介紹:
1)java.lang----包含一些Java語言的核心類,如String、Math、Integer、 System和 Thread,提供常用功能
2)java.net----包含執行與網路相關的操作的類和介面。
3)java.io ----包含能提供多種輸入/輸出功能的類。
4)java.util----包含一些實用工具類,如定義系統特性、介面的集合框架類、使用與日 期日曆相關的函數。
5)java.text----包含了一些java格式化相關的類
6)java.sql----包含了java進行JDBC資料庫編程的相關類/介面
7)java.awt----包含了構成抽象視窗工具集(abstract window toolkits)的多個類,這 些類被用來構建和管理應用程式的圖形用戶界面(GUI)。 B/S C/S
2. import的使用:
import:導入
1)在源文件中顯式的使用import結構導入指定包下的類、介面
2)聲明在包的聲明和類的聲明之間
3)如果需要導入多個結構,則併列寫出即可
4)可以使用"xxx.*"的方式,表示可以導入xxx包下的所有結構
5)如果使用的類或介面是java.lang包下定義的,則可以省略import結構
6)如果使用的類或介面是本包下定義的,則可以省略import結構
7)如果在源文件中,使用了不同包下的同名的類,則必須至少有一個類需要以全類名的方式顯示。
8)使用"xxx.*"方式表明可以調用xxx包下的所有結構。但是如果使用的是xxx子包下的結構,則仍需要顯式導入
9)import static:導入指定類或介面中的靜態結構:屬性或方法。