JAVASE筆記回顧

第一部分,JAVA基礎和麪向對象

part01 入門與開發環境搭建

1: 計算機基礎知識(了解)
(1)計算機
(2)計算機硬件
(3)計算機軟件
系統軟件:windows,linux,mac
應用軟件:QQ,YY,掃雷,CS/F
(4)軟件開發
就是用開發工具和計算機語言作出軟件
(5)計算機語言
人與計算機的交流方式
(6)人機交互
A:圖像界面方便,簡單,直觀。
B:DOS 窗口方式要有控制檯, 要記住不少的命令, 麻煩。
(7)鍵盤功能鍵和快捷鍵的介紹(掌握)
A:鍵盤功能鍵
tab
shift
ctrl
alt
空格
enter
windows 鍵
PrtSc
上下左右
B:鍵盤快捷鍵(補齊中文意思)
ctrl+A 全選
ctrl+C 賦值
ctrl+V 粘貼
ctrl+X 前切
ctrl+Z 撤銷
ctrl+S 保存
(8)經常使用的DOS 命令
A:如何打開控制檯
win+R -- cmd -- 回車
B:經常使用的命令
d:回車切換盤符
cd demo 回車進入目錄
cd.. 返回上一級目錄
cd\ 返回跟目錄
cls 清屏
exit 退出
2: Java 語言概述
(1)Java 語言的發展史
Java 之父-- 詹姆斯·高斯林(James Gosling)
(2)Java 語言的平臺
A:J2SE 基礎版,桌面應用
B:J2ME 微型版,手機開發(android,ios)
C:J2EE 企業版,全部瀏覽器訪問的應用程序。
注意:JDK5 之後更名JavaSE,JavaME,JavaEE
J2SE 是學習其餘兩門的基礎。
(3)Java 語言的特色
其餘的不少特色...
開源:源代碼開放
跨平臺:在任意操做系統下均可以使用。
(4)跨平臺
經過火星人和中國,德國人的交流知道的原理,找一個翻譯。而java 語言的這個翻譯是jvm 。
注意:java 語言是跨平臺的,jvm 不是跨平臺的。
(5)JRE 和JDK(掌握)
JRE: JVM + class library 運行環境:虛擬機+核心類庫
JDK: JRE + tools 開發工具包:運行環境+
一句話:有JDK 開發的軟件,必須在JRE 上運行,並由JVM 保證跨平臺。
3:JDK 的下載與安裝(掌握)
(1)JDK 的下載。
經過官網: http://www.oracle.com
(2)JDK 的安裝
A:傻瓜式安裝, 會點擊下一步便可。
B:注意:
a:請不要在中文目錄和有特殊字符的目錄(空格)
b:請把全部開發相關的軟件放到一個目錄中。
C:JRE 是不須要單獨安裝的。
4:HelloWorld 案例
(1)開發工具
A:記事本windows 自帶的
B:高級記事本EditPlus
C:集成開發工具Eclipse/MyEclipse
(2)一個HelloWorld 案例
最終代碼:
class Demo
{
public static void main(String[] args)
{
System.out.println("Hello World");
}
}
解釋:
A:java 語言的最基本單位是類。用class 表示
定義類的格式:
class 類名
B:程序若是要運行, 就必須有main 方法, 它是被jvm 調用。
格式:
public static void main(String[] args)
C:程序若是要輸出一些內容, 就必須使用輸出語句。
格式:
S ystem.out.println("Hello World");
(3)一個Java 程序的執行。
A:開發源程序(.java 文件)
Demo.java
B:經過javac 命令編譯(.class)
javac Demo.java
C:經過java 命令執行
java Demo
(4)常見的錯誤及注意事項
A:文件擴展名致使編譯失敗。把隱藏文件擴展名給顯示出來。
win7,win8 的同窗若是不會單獨問我。
B:非法字符錯誤
只要看到是非法字符, 確定是中英文問題。
由於咱們要求全部的符號所有是英文狀態的。
C:注意大小寫問題
class -- Class
String -- string
System -- system
D:括號的對應問題
在java 程序中,括號都是成對出現的。
因此建議在編寫程序時,請遇到括號,成對打。
E:main 方法格式錯誤
public static void main(String [] args){ }
F:當java 源文件發生變化後, 請重寫編譯在運行
G:縮進問題:寫代碼遇到{}縮進一個tab 位置。
5:環境變量
(1)path 環境變量的做用
讓javac 和java 命令能夠在任意的目錄下使用。
(2)path 環境變量的配置(掌握)
A:只修改path
D:\develop\Java\jdk1.7.0_45\bin;之前的path
**B:先創建一個JAVA_HOME,後修改path**
新建:JAVA_HOME 值是D:\develop\Java\jdk1.7.0_45
修改:%JAVA_HOME%\bin;之前的path
推薦使用B 方案。
(3)classpath 環境變量的配置
讓指定的class 文件在任意目錄均可以被訪問。
技巧: 在最左邊配置一個;
這樣作的好處就是可以先在當前目錄下查找並執行。 java

part02 常量、數據類型與運算符

1:常量
(1)在程序的運行過程當中其值是不能夠發生改變的量。
(2)常量的分類:
1:字面值常量
1:整數常量
12,-23
2:實數常量
12.5,-65.43
3:字符常量
'a','A','0'
4:字符串常量
"hello"
5: 布爾常量
true,false
6:空常量null
2:自定義常量
(3)常量能夠直接被輸出。
2:進制
(1)是一種進位的方式,X 進製表示逢x 進1 。
(2)Java 中整數常量的表示
1: 二進制由0,1 組成。以0b 開頭。JDK7 之後的新特性。
2: 八進制由0-7 組成。以0 開頭。
3: 十進制由0-9 組成。默認就是十進制。
4: 十六進制由0-9, A-F(不區分大小寫)組成, 以0x 開頭。
(3)進制轉換:
1: 其餘進制到十進制
係數: 就是每一位上的數據。
基數: X 進制, 基數就是X 。
權: 在右邊, 從0 開始編號, 對應位上的編號即爲該位的權。
結果: 把係數*基數的權次冪相加便可。:
2: 十進制到其餘進制
除基取餘, 直到商爲0, 餘數反轉。
3: 快速轉換
1): 8421 碼。
2): 二進制--八進制(3 位組合)
3): 二進制--十六進制(4 位組合)
3: 變量(掌握)
(1)程序的運行過程當中, 在指定範圍內發生改變的量。
(2)格式:
數據類型 變量名= 初始化值;
變形格式:
數據類型 變量名;
變量名= 初始化值;
舉例:
方式1: byte b = 10;
方式2: byte b;
b = 10;
4: 數據類型(掌握)
(1)分類
基本類型: 4 類8 種。
引用類型: 類, 接口, 數組。(了解)
(2)基本類型
整型:
byte 1個字節
short 2個字節
int 4個字節
long 8個字節
浮點型:
float 4個字節
double 8個字節
字符型:
char 2個字節
布爾型:
boolean 不明確。能夠認爲是1 個字節。
注意:
整數默認是int 類型。long 類型須要加L 或者l 後綴。
浮點數默認是double 類型。float 類型須要加F 或者f 後綴。
(3)類型轉換
1: boolean 類型不參與轉換。
2: 隱式轉換(從小到大)
byte,short,char -- int -- long -- float -- double
3: 強制轉換(從大到小)
格式:(數據類型)數據;
(4)面試題
byte b1 = 3;
byte b2 = 4;
byte b3 = b1 + b2;
byte b4 = 3 + 4;//報錯,int類型沒法賦值給byte類型
5: 運算符(掌握)
(1)就是把常量和變量鏈接的符號, 通常參與運算使用。
(2)分類:
算術運算符
賦值運算符
關係運算符
邏輯運算符
位運算符
三元運算符
(3)算術運算符:+,-,*,/,%,++,--
+: 正號, 加法, 字符串鏈接符。
System.out.println("5+5="+5+5);//5+5=55
System.out.println(5+5+"=5+5");//10=5+5
%: 模運算, 取餘數
左邊若是大於右邊, 結果是餘數。
左邊若是小於右邊, 結果是左邊。
左邊若是等於右邊, 結果是0 。
正負號跟左邊一致。
++/--:
++ 其實至關於把數據+1
單獨使用:在數據的先後, 結果一致。
參與操做使用:
若是在數據的後邊, 數據先操做, 在++/--
若是在數據的前邊, 數據先++/--, 在操做。
(4)賦值運算符
=,+=,-=,*=,/=,%=
int a = 10;
把10 賦值給int 類型的變量a 。
a += 20;
把左邊和右邊的和賦值給左邊。
注意事項:
a = a + 20;
a += 20;
結果是等價的,效果不是等價的。
+=運算內含了強制類型轉換功能。
好比:
s hort s = 2;
s+=3;
等價於
s = (short)(s+3);
(5)關係運算符
==,!=,>,>=,<,<=
特色: 關係運算符的結果都是boolean 類型。
請千萬注意: == 不要寫成=
(6)邏輯運算符
&,|,!,^,&&,||
&:有false 則false
|:有true 則true
!:true 變false,false 變true
^:相同false,不同true
&&:有false 則false
||:有true 則true
&&和&的區別是: 若是左邊有false 了, 右邊將不再執行。
||和|的區別是: 若是左邊有true 了, 右邊將不再執行。
開發中經常使用:
&&,||,?!(s+3)?; linux

part03 運算符與流程控制語句

1: 運算符(掌握)
(1)位運算符(了解)
^ : 一個數據對同一個數據^兩次, 結果仍是數據自己。
舉例: a ^ b ^ b = a
(2)條件運算符
格式:
條件表達式?表達式1:表達式2
執行流程:
根據條件表達式返回的是true 仍是false, 決定結果是什麼。
若是是true,就把表達式1 做爲結果。
若是是false,就把表達式2 做爲結果。
舉例:
int a = 100;
int b = a > 50 ? 200 : 100;
請問b 的值?200
2: 面試題(理解)
(1)請用最有效率的代碼寫出2 乘以8
2<<3
(2)請交換兩個變量。
int a = 10;
int b = 20;
開發: 臨時變量
int temp = a;
a = b;
b = temp;
面試: 位^運算符
a = a ^ b;
b = a ^ b;//即b=a^b^b=a
a = a ^ b;//即a=a^b^a=b
3: if 語句(掌握)
(1)用於作判斷使用的。
常見於對某個範圍進行判斷, 或者幾個變量進行判斷, 還有就是boolean 表達式的判
斷。
(2)格式:
A:第一種格式: 一種狀況
if(條件表達式)
{
語句體;
}
執行流程:
若是條件表達式爲true, 就執行語句體;
不然, 什麼都不執行。
B:第二種格式: 兩種狀況
if(條件表達式)
{
語句體1;
}
else
{
語句體2;
}
執行流程:
若是條件表達式爲true, 就執行語句體1;
不然, 就執行語句體2;
特殊:
能夠和條件表達式在某些狀況下進行替換。
通常是在賦值的狀況下能夠。
舉例:
獲取兩個數中的最大值。
C:第三種格式: 多種狀況
if(條件表達式1)
{
語句體1;
}
else if(條件表達式2)
{
語句體2;
}.
..
else
{
語句體n;
}
執行流程:
若是條件表達式1 爲true, 就執行語句體1;
若是條件表達式2 爲true, 就執行語句體2;
...不然, 就執行語句體n;
D:注意事項
a:何時時候哪種if 語句。
第一種格式在判斷條件爲一種狀況下使用。
第二種格式在判斷條件爲兩種狀況下使用。
第三種格式在判斷條件爲多種狀況下使用。
b:每一種if 語句其實都是一個總體, 若是有地方執行了,
其餘的就不執行了。
c:若是if 或者else 裏面控制的語句體是一條語句, 是能夠省略大括號的,
可是, 若是是控制多條語句, 就必須寫上大括號。
建議: 永遠寫上大括號。
d:大括號和分號通常不同時出現。
E:做用域
全部變量的定義只在它所屬的大括號內有效。
(3)案例:
A:根據鍵盤錄入的成績, 判斷等級。
B:根據鍵盤錄入的月份, 輸出該月份所對應的季節。
4: switch 語句(掌握)
(1)用於作選擇使用的。通常用於幾個常量的判斷。
switch 會把幾個常量值直接加載到內存, 在判斷的時候, 效率要比if 高。
因此, 針對幾個常量的判斷, 通常選擇switch 語句。
(2)switch 語句的格式:
switch(表達式)
{
case 值1:
語句體1;
break;
case 值2:
語句體2;
break;
case 值3:
語句體3;
break;
...
default:
語句體n;
break;
}
A:針對格式的解釋
switch:表示這裏使用的是switch 語句, 後面跟的是選項。
表達式: byte,short,int,char
JDK5 之後能夠是枚舉(之後講)
JDK7 之後能夠是字符串(後面講)
case:表示這裏就是選項的值, 它後面的值未來和表達式的值進行匹配。
case 後面的值是不可以重複的。
break:
switch 語句執行到這裏, 就結束了。
default:
當全部的case 和表達式都不匹配的時候, 就走default 的內容。
它至關於if 語句的else 。通常不建議省略。
B:執行流程
進入switch 語句後, 就會根據表達式的值去找對應的case 值。
若是最終沒有找到, 那麼, 就執行default 的內容。
C:注意事項:
a:default 總體能夠省略嗎?
能夠,可是不建議。
b:default 的位置能夠放到前面嗎?
能夠,可是不建議。
c:break 能夠省略嗎?
能夠,可是不建議。
default 在最後, break 是能夠省略的。
case 後面的break 能夠省略, 可是結果可能有問題。
d:switch 語句何時結束呢?
就是遇到break 或者執行到程序的末尾。
(3)案例:
A:根據鍵盤錄入的日期(1-7),輸出對應的星期日期。
B:根據鍵盤錄入的月份, 輸出該月份所對應的季節。(選作)
5: Scanner 的使用(掌握)
(1)Scanner 是JDK5 之後設計的用來接收鍵盤錄入數據使用的。
(2)目前咱們要經過鍵盤錄入int 類型數據,必須按照以下步驟:
A:導包
import java.util.Scanner;
B:建立對象,封裝鍵盤錄入
Scanner sc = new Scanner(System.in);
C:調用方法,獲取數據
int number = sc.nextInt();android

part04 循環結構

1: 循環(掌握)
(1)若是發現有不少重複的內容的時候就考慮使用循環改進代碼,讓代碼看起來簡潔了。
(2)循環的組成
A:循環體,就是要作的事情。
B:初始化條件:通常定義的是一個初始變量
C:判斷條件:用於控制循環的結束。
D:控制條件:用於控制變量的變化。通常都是一個++/--操做。
(3)循環的分類:
A:for循環ios

for(初始化條件;判斷條件;控制條件)
{循環體;}
執行流程:
a:先執行初始化條件;
b:執行判斷條件
c:根據判斷條件的返回值:
true:執行循環體。
false:就結束循環。
d:最後執行控制條件。返回到b 繼續。
B:while循環:先判斷再循環面試

初始化條件;
while(判斷條件)
{
循環體;
控制條件;
}
執行流程:
a:先執行初始化條件;
b:執行判斷條件
c:根據判斷條件的返回值:
true:執行循環體。
false:就結束循環。
d:最後執行控制條件。返回到b 繼續。
C:do...while循環:先循環再判斷(循環至少執行一次)
初始化條件;
do{
循環體;
控制條件;
}while(判斷條件);
執行流程:
a:先執行初始化條件;
b:執行循環體和控制條件;
c:執行判斷條件
d:根據返回值
true:返回b。
false:就結束循環。
注意:
a:通常使用for循環或者while 循環,並且這兩種循環是能夠等價轉換的。
b:do...while 循環至少執行一次循環體。
(4)案例: (掌握)
A:求5 的階乘。
B:水仙花。
C:統計疊多少次, 能疊成珠穆朗瑪峯的高度。
(5)循環嵌套: (理解)
A:也就是循環語句的循環體是一個循環語句。
B:經過輸出
****
****
****
咱們不斷的改進。發現了一個問題:
外循環控制行數,內循環控制列數。
(6)案例: (理解)
A:正三角形
內循環的判斷條件: y<=x
for(int x=0; x<5; x++)
{
for(int y=0; y<=x; y++)
{
System.out.print("*");
}
System.out.println();
}
B:倒三角形
內循環的初始化條件: y=x
for(int x=0; x<5; x++)
{
for(int y=x; y<5; y++)
{
System.out.print("*");
}
System.out.println();
}
C:九九乘法表
2: break 和continue(掌握)
(1)有時咱們須要對循環進行一些控制終止,就用到兩個關鍵字:
break 和continue
(2)特色:
A:它們都必須在循環中(break 還能夠在switch 中) 。
通常在循環的判斷中。
B:若是單獨使用break 和continue,後面是不能有語句的。
(3)區別:
A:break 結束當前循環。
B:continue 結束本次循環,進入下一次循環。
(4)如何退出嵌套循環: (了解)
用帶標籤的循環。
格式:
標籤名: for(){
for(){if()
{
break 標籤名;
}
}
}
3:應用場景(總結)
(1)變量:發現有一個數據是變化的時候就用變量。
(2)if 語句:若是是一個範圍的判斷,boolean 類型的表達式的判斷,幾個數據的判斷。
(3)switch 語句:幾個數據的判斷。通常這種狀況有限選擇switch 。
(4)for 語句:若是次數或者範圍特別明確。(水仙花)
(5)while 語句:若是次數或者範圍不明確。(珠穆朗瑪峯)正則表達式

part05 函數與數組

1: 函數(掌握)
(1)定義在類中,有特定功能的一段小程序。
(2)函數的格式:
修飾符 返回值類型 函數名(形參類型 形式參數1, 形參類型 形式參數2...)
{
函數體;
reutrn 返回值;
}
A:修飾符public static
B:返回值類型程序最終結果的數據類型
C:函數名其實就是函數的名稱,方便咱們調用。
D:參數
形參類型數據類型
形式參數就是接收實際參數的變量
實際參數就是實際參與操做的變量(常量)
E:函數體就是按照正常的邏輯完成功能的代碼。
F:返回值就是程序的最終結果
G:reutrn 返回值哪裏調用程序,return 就把結果返回到哪裏。
(3)函數的特色:
A:函數與函數之間是平級關係。不能在函數中定義函數。
B:運行特色:函數只有被調用纔會被執行。
(4)案例:
有明確返回值的例子:
A:求兩個數據的和
B:求兩個數據的最大值
C:比較兩個數是否相等
void 類型例子:
A:nn 乘法表
B:根據給定的行和列輸出一個*組成的長方形
(5)函數的調用
A:有明確返回值
a:單獨調用通常沒有意義。
b:輸出調用可是若是想拿結果繼續操做 就有問題了。因此,不好。
c:賦值調用推薦方式。
B:void 類型
單獨調用
(6)函數重載
A:函數名相同,參數列表不同(個數不同,對應的類型不同) ,與返回值類型無關。
B:舉例:
public static int sum(int a,int b){...}
public static int sum(int a,int b,int c){...}
public static int sum(float a,float b){...}
2: 數組(掌握)
(1)數組是存儲同一種類型的多個元素的容器。
(2)好處:數組中的元素會被自動從0 開始編號,方便獲取。
(3)格式:
A:int[] arr = new int[3];
B:int arr[] = new int[3];
C:int[] arr = new int[]{1,2,3};
D:int[] arr = {1,2,3};
推薦A 和D 。
(4)Java 內存圖:
A:棧:存儲局部變量使用,使用完畢立馬消失。
B:堆:全部new 出來的都在堆裏面。
a:每個實體都有地址值
b:每個實體內的內容都有默認值
整數:0
浮點數:0.0
字符:'\u0000'
布爾:false
c:在垃圾回收器空閒的時候被回收。
C:方法區
D:本地方法區
E:寄存器
(5)操做:
數組的索引:index
數組的長度:arr.length();
數組名
A:數組的遍歷算法

for(int a:arr){操做a;}
B:數組獲取最值:max();min();
C:數組的查找:二分查找
(6)二維數組:數組裏面套了一層數組
格式:
A:int[][] arr = new int[3][2];
B:int[][] arr = new int[3][];
C:int[][] arr = {{1,2,3},{4,5},{6,7,8,9}};
遍歷:
應用:遍歷求和。數據庫

part06 面向對象

1: Java 中的參數傳遞問題
基本類型:形式參數的改變對實際參數沒有影響。
引用類型:形式參數的改變直接影響實際參數,形參改變意味着地址值改變
2: 面向對象(理解)
(1)面向對象:是基於面向過程的一種思想。
面向過程:以函數爲基礎,關注實現過程。--具備某種功能的模塊
面向對象:以對象爲基礎,關注實現結果。--具備某些功能的一個系統(有機總體)
(2)面向對象的思想特色:
A:是一種更符合人們思考習慣的思想。
B:把複雜的事情簡單化了。
C:把咱們從執行者變成了指揮者。
舉例:
買電腦,洗衣,作飯,旅遊。
(3)事物是如何體現的呢?
A:屬性:有哪些特徵
B:行爲:有哪些功能
(4)類與對象的關係:
把事物轉換成類:
A:成員變量
定義在類中方法外。
B:成員方法
和之前的區別是去掉static 。
類:是相關的屬性和行爲的集合,是一個抽象的概念。
對象:是某種事物的具體存在,是類的具體表現形式。
舉例:
類:學生
對象:張三
(5)案例:
A:學生類
B:手機類
C:汽車類
(6)如何使用呢?
A:建立對象
格式:
類名 對象名= new 類名();(其實是調用類的構造器來建立對象)
B:使用成員變量和成員方法
對象名.成員變量
對象名.成員方法編程

part07 面向對象的特徵之一:封裝

1: 封裝(理解)
(1)隱藏實現的細節,提供公共的訪問方式。
類,方法等其實都是封裝的具體體現。
(2)private 關鍵字
A:用於修飾成員變量和成員方法。
B:被修飾的內容在其餘類中是不能夠被訪問的。
(3)常見的應用:
類中的全部成員變量私有,給出對應的get/set 方法。
代碼體現:
class Student
{
private String name;
private int age;
public Student(){}
public Student(String name,int age)
{
this.name = name;
this.age = age;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return age;
}
}
2: 構造方法(構造器)
(1)格式及特色
格式:
訪問權限修飾符 類名(參數...){}
訪問權限修飾符:
public,private
特色:
A:方法名和類名相同
B:沒有返回值類型
C:沒有具體的返回值
(2)注意事項:
A:若是你不給構造方法,jvm 會自動給你一個無參構造方法。
B:若是你給出了構造方法,那麼jvm 將不再提供無參構造方法。
此時若是要使用無參構造方法:只能本身提供
推薦:永遠手動給出無參構造方法。
3: this 關鍵字(掌握)
(1)是一個關鍵字。表明當前類對象的引用。
簡單記:在方法中,哪一個對象調用方法this 就表明誰。
除了靜態方法外,全部的方法中有隱含的有一個this 引用
(2)應用場景:
解決局部變量隱藏成員變量問題。
4:static 關鍵字
(1)是一個關鍵字。能夠修飾成員變量和成員方法。
(2)靜態的特色:
A:隨着類的加載而加載
B:優先於對象存在
C:被類的全部對象共享
D:能夠經過類名調用
(3)靜態的注意事項:
A:在靜態方法中是沒有this 關鍵字的。
B:靜態方法只能訪問靜態成員。
(4)靜態內容的調用:
A:被對象調用
B:被類名調用
推薦被類名調用。
(5)何時該用static 呢?
若是某個內容是全部對象共享的就用靜態修飾。
舉例:
水杯和飲水機。
廁所和人。
老師和學生。
5:Math 類的隨機數(掌握)
類名調用靜態方法。
包: java.lang
類: Math
方法: public static double random():
java.lang 包下的類是不用導包就能夠直接使用的。
產生1-100 之間的隨機數:
int number = (int)(Math.random()*100)+1;小程序

part08 面向對象的特徵之二:繼承

1: 繼承(掌握)
(1)把多個類中的相同的屬性和行爲進行抽取,封裝到一個類中,而後再創建新類的時候,不須要從頭作起,繼承剛纔定義的那個類便可。
(2)好處:
A:提升代碼的複用性。
B:讓類與類之間產生了一個關係,是多態的前提。
(3)何時使用繼承?
A:若是類之間存在着:is a 的關係,就能夠考慮使用繼承。
B:不要爲了繼承部分功能,而去使用繼承。
(4)繼承的特色:
A:Java 只支持單繼承,不支持多繼承。(一個兒子只能一個爹)
爲何?若是支持多繼承,就會出現調用不明確的問題。
B:Java 支持多層(重)繼承。
(5)super 和this 的區別?
A:super 是一個關鍵字,表明父類的存儲空間標識。(能夠理解爲父親的引用)
B:它和this 的用法類似
a:成員變量
this.變量-- 本類的
super.變量-- 父類的
b:構造方法
this(...) -- 本類的
super(...) -- 父類的
c:成員方法
this.方法名() -- 本類的
super.方法名() -- 父類的
(6)子父類中成員變量的用法:
A:名稱不同,這個太簡單了。
B:名稱相同,子類對象的在使用的時候:
先找子類局部範圍
再找子類成員範圍
最後找父類成員範圍
(7)子父類中成員方法的用法:
A:名稱不同,這個太簡單了。
B:名稱相同,子類對象的在使用的時候:
先找子類的
再找父類的
C:方法重寫
在子類中,方法聲明(修飾符,返回值,方法名,參數列表)相同的狀況。
注意事項:
a:父類中私有方法是不能被重寫
b:子類方法的訪問權限必定要大於等於父類的訪問權限
c:靜態只能重寫靜態(靜態跟類相關)
(8)子父類中構造方法的用法:
A:子類的初始化過程當中,首先會去執行父類的初始化動做。
由於子類的構造方法中默認有一個super() 。
爲何?子類要使用父類的成員變量,這個初始化必須在子類初始化以前完成。
因此子類的初始化過程當中會先執行父類的初始化。
B:若是父類沒有無參構造方法
A:使用super 調用父類的帶參構造。推薦方式。
B:使用this 調用自己的其餘構造。
2: 代碼塊(面試題, 理解)
(1)執行順序:
靜態代碼塊(隨着類的加載而加載)--> 構造代碼塊(每次建立對象時調用)--> 構造方法(初始化對象)
(2)注意事項:
靜態代碼塊只執行一次
3:final(掌握)
(1)是一個關鍵字,能夠用於修飾類、成員變量、成員方法。
(2)特色:
它修飾的類不能被繼承。
它修飾的成員變量是一個常量。
它修飾的成員方法是不能被子類重寫的。

part09 面向對象的特徵之三:多態;抽象類、接口

1:多態(掌握)
(1)對象在不同時刻表現出來的不同狀態。
舉例:狗(狗、寵物、動物)

典型表現形式:用接口來接收類所建立的對象
(2)多態的前提
A:要有繼承或者實現關係。
B:要有方法的重寫/實現。
C:要有父類引用或者父接口引用指向子類對象。
注意:多態有三種體現形式:
類多態
抽象類多態
接口多態
(3)多態中的成員特色:
A:成員變量
編譯看左邊,運行看左邊。
B:成員方法
編譯看左邊,運行看右邊。
爲何?由於方法存在重寫,而變量沒有。
舉例:孔子扮父。
(4)多態的弊端:
父類(接口)引用不能使用子類特有功能。
爲了解決這個弊端須要向下轉型。
Fu f = new Zi(); //向上轉型
Zi z = (Zi)f; //向下轉型
Zi z = new Zi();
(5)多態的好處:
能夠提升代碼的擴展性和可維護性。
2:抽象類:聲明具備某些功能的一種類
(1)若是多個類中存在相同的方法聲明,而方法體不同樣,咱們就能夠只提取方法聲明。
若是一個方法只有方法聲明,沒有方法體,那麼這個方法必須用抽象修飾。而一個類中若是有抽象方法,這個類必須定義爲抽象類。
(2)抽象類的特色
A:抽象類和抽象方法必須使用abstract 修飾
B:抽象類不能被實例化
C:抽象類有構造方法,用於子類實例化使用
D:若是一個類是抽象類,那麼繼承它的子類要麼是抽象類,要麼重寫全部抽象方法。
(3)抽象類的成員特色
A:成員變量能夠變量也能夠是常量
B:擁有構造方法
C:成員方法能夠有抽象方法也能夠有非抽象方法(全是抽象方法或者非抽象方法都是能夠的)
(4)抽象類的幾個小問題
A:抽象類不能被實例化,爲何有構造?用於子類實例化使用。
B:一個類沒有抽象方法,爲何定義爲抽象類?不想被實例化,或者是抽取出來的一個規則類
C:abstract 不能和哪些關鍵字共存:final、private、static
3:接口(理解)
(1)若是一個抽象類中的方法都是抽象的, 這個時候, java 就提供了一種
更抽象的表示形式:----接口
接口:interface
實現:implements
格式:
interface 接口名{}
class 類名implements 接口名{}
(2)接口的特色:
A:接口不能被實例化。
B:一個類若是實現了接口:要麼是抽象類、要麼實現接口中的全部方法。
(3)接口的成員特色:
A:成員變量只能是常量(只能讀不能改)。默認修飾符public static final
B:成員方法只能是抽象方法。默認修飾符public abstract
推薦:永遠手動給出修飾符。
(4)接口的思想特色:
A:對外暴露的規則
B:是功能的擴展
C:下降耦合度
耦合:類與類的關係
內聚:類本身完成某件事情的能力
編程追求的目標:高內聚低耦合
D:接口能夠多實現。
(5)類,接口的關係
A:類與類
繼承關係,只能單繼承能夠多層繼承。
B:類與接口
實現關係,能夠單實現也能夠多實現;還能夠在繼承一個類的同時實現多個接口。
C:接口與接口
繼承關係,能夠單繼承也能夠多繼承。
(6)抽象類和接口的關係
接口是一種特殊的抽象類,比抽象類更抽象,接口裏的方法全爲抽象方法

part10 包、權限修飾符、內部類

1:包(掌握)
(1)包其實就是文件夾,用於區分相同的類名。
(2)格式:package 包名1.包名2...;
(3)帶包的編譯和運行
1:手動建包;2:自動建包
2:導包(掌握)
(1)通常來講用一個類,須要用該類的全路徑名稱。若是多個地方使用就比較麻煩,因此java 提供了導包操做。
(2)格式:
import 包名1.包名2...類名;
//下面這種屬於把指定包下的類都導入。這種用法不推薦。咱們應該用誰導誰。
import 包名1.包名2...*;
(3)package,import,class 的順序
package -- import -- class
3: 四種權限修飾符(掌握)
 image
4:注意,常見規則以下:
之後,全部的類都用public 修飾。而且在一個java 文件中只寫一個類。
之後,全部的成員變量用private 修飾。
之後,全部的成員方法用public 修飾。
若是是抽象類或者接口:
public abstract + ...
之後,全部的構造方法用public 修飾。
若是類是工具類或者單例類:構造用private 修飾
5:內部類
(1)把類定義在一個類的內部。
(2)訪問特色:
1:內部類能夠直接訪問外部類成員,包括私有
2:外部類要想訪問內部類成員,必須建立對象。
(3)內部類分類:
1:成員位置:private 安全;static 方便調用
2:局部位置:定義在方法中
局部內部類訪問局部變量必須加final 修飾,延遲生命週期。
(4)匿名內部類
1:是定義在局部位置的沒有名字的內部類。
2:前提:存在一個類、抽象類或者接口。
3:格式
new  類或者接口名()
{重寫方法;}
本質理解:其實這是一個繼承類或者實現接口的匿名的子類對象。
4:使用
當你看到方法的形式參數是接口或者抽象類的時候,用匿名內部類改進。

匿名內部類只能使用一次,一般用來簡化代碼書寫。

 

第二部分 經常使用API和集合

part11 IDE和Object類

Eclipse
1:Eclipse 的概述
(1)eclipse 的由來:由IBM 一個小組開發
(2)eclipse 的特色
A:徹底由Java 語言編寫的工具。
B:不須要安裝
C:免費的:eclipse.org
D:開源的
E:擴展性很是強
(3)eclipse 和MyEclipse 的區別
A:MyEclipse 是基於eclipse 加入了一些用於開發Web 的插件並對這些本身開發的插件進行收費。
B:特色MyEclipse 集成性很好。
(4)在使用eclipse 以前,系統中必需要先有JDK 或者JRE 。
由於eclipse 就是用Java 語言編寫的程序,因此須要jvm 的解釋執行。
A:對於高版本的MyEclipse,內部已經集成了JDK 。因此安裝後會用本身的JDK 來執行MyEclipse 。
2:Eclipse 安裝
A:解壓Eclipse 壓縮包
B:複製到制定的目錄(不要有中文、空格或其餘非法字符)
3:Eclipse 的使用
A:打開軟件的界面
B:新建一個項目(工程)
C:在項目下的src(源碼包)下創建包
D:在包下創建類
E:在類裏邊寫代碼
F:編譯源文件(代碼寫完保存的時候會自動生成class 文件, 在項目的bin 目錄下。)
G:執行class 文件(右鍵-- Run As -- Java Application)
H:結果顯示在Console 控制檯上
4:Eclipse 的基本設置
A:在代碼最左側前面, 右鍵- Show Line Numbers, 如何取消?再次選擇
B:java 代碼字體,Window -- Preferences -- Appearance -- Colors and Fonts -- Java --
Java Editor -- 選擇右邊的Edit 進行修改便可。
C:若是不當心把界面給弄沒了不要擔憂有復位操做,window -- reset ...
5:Eclipse 的內容輔助鍵
Alt+/
main 方法:先寫main 而後alt+/最後Enter
輸出語句:先寫syso 而後alt+/最後Enter
for 循環:先寫for 而後alt+/最後Enter
6:Eclipse 的快捷鍵
(A,E,F 必須掌握)
A:alt+/ 內容輔助鍵:補充類或者接口名,幫咱們起變量名,new 後面直接提示等。
B:ctrl+/ 單行註釋,在按一次,取消單行註釋
C:ctrl+shift+/ 對選中的區域進行多行註釋的封裝
D:ctrl+shift+\ 用於取消多行註釋,只要光標在多行註釋中便可
E:ctrl+shift+o 對使用了其餘包中的類或者接口進行自動導入
F:ctrl+shift+f 對代碼進行格式化
G:alt+上鍵向上移動當前行或者選中行
H:alt+下鍵向下移動當前行或者選中行
I:ctrl+d 刪除當前行,或者刪除選中行
J:ctrl+shift+x 將選中部分的字母大寫
K:ctrl+shift+y 將選中部分的字母小寫
L:ctrl+1 光標放在編譯中出現紅色波浪線提示的內容上,在該快捷鍵能夠獲取建議的處理方式
M:F3 能夠查看類或者方法的源碼,前提是該原碼已經關聯。
7:Eclipse 的自動給出set,get 方法
右鍵--source--(set, get 方法)Generate Setters and Getters
(有參構造)Generate Constructor using Fields...
(無參構造)Generate Constructors form Superclass..
8:Eclipse 刪除和導入項目
刪除:選中項目-- 右鍵delete ...
A:從工做臺中刪除
B:從硬盤刪除
導入:在項目所在位置的空白處右鍵--》Import --》General --》Existing Project...(最長的那個)
9:Eclipse 的debug 調試
A:如何加斷點
在你想看從哪裏執行的程序的左邊雙擊便可。(不要在註釋上作)
在哪裏加?哪裏不會加哪裏,最好在每一個方法的第一條語句上加。
B:如何使用
右鍵-- Debug As -- Java Application
彈出一個界面問你:是否打開調試界面。yes是否記住個人選擇。選中框框便可
C:查看哪裏
左邊:程序運行到哪裏了
右邊:變量的變化過程
D:怎麼繼續:F6 執行一行。
E:去除斷點
方式1:在點擊的那個地方再次點擊
方式2:在debug 調試界面--BreakPoints -- remove All...
F:補充:
F5 跳入;F8 跳到下一個斷點
演示建立對象的整個過程
Object 類的方法
1:建立Student 對象並打印效果
A:打印他的時候,默認調用的他的toString 方法
B:Student 沒有toString 方法,調用的是Object 的toString 方法
C:object 的toString 方法返回值是包名...類名+@+16 進制地址值,咱們通常使用toString 方法都要重寫他
2:關於==作比較的問題
A:基本類型的比較:比較的是值
B:引用類型的比較:比較的是引用類型所指向的地址值
3:本身實現對象的成員變量數據的比較
「2」,「3」目的是爲了引出Object 中的equals 方法
4:Object 中的equals 方法
源碼其實就是用「==」比較的兩個變量或對象的引用

對於string和包裝類,object類的equals()方法比較規則爲:若是兩個對象類型和內容一致則返回true;

也可自定義重寫object的equals()方法:好比兩個都是person類而且屬性name也相同返回true。
5:String 類中的equals 方法
equals比較兩個字符串是否同樣

「==」比較的是變量或對象的引用
1: Scanner 注意事項
存在的問題:當錄入數據依次是int String,而且分別使用nextInt()和next()方法獲取數據的時候會接受不到String 數據。
解決辦法:
1). 在錄入完int 後從新建立一個新的Scanner 對象
2). 用字符串接受,而後把字符串轉成int 類型
2:數據結構思想:拿時間換空間,拿空間換時間
例子: 需求:一個網站有一個功能,當填入你的年齡的時候就能自動判斷你是哪一個年齡段
0-9 歲, 兒童
10-19 歲, 少年
20-29 歲, 青年
30-39 歲, 壯年
40-49 歲, 中年
50-59 歲, 中老年
60 歲以上, 老年
代碼實現例子:
String[] ages = {"兒童","少年","青年","中年","中老年","老年"};
System.out.println(ages[age/10]);

part12 經常使用API--String類

2: String 類(掌握)
(1)字符串:多個字符組成的一串數據。
(2)構造方法:
A:String s = new String();無參構造
B:String s = new String(byte[] bys);byte 數組轉成字符串
C:String s = new String(byte[] bys,int index,int length);
從哪一個地方截取byte 數組幾個轉成字符串(把字節數組的一部分轉爲字符串)
D:String s = new String(char[] chs);
字符數組轉字符串(把字符數組的一部分轉爲字符串)
E:String s = new String(char[] chs,int index,int length);
從哪一個地方截取char 數組幾個轉成字符串
F:String s = new String(String str);字符串裏傳一個字符串
G:String s = "hello";
(3)字符串的特色及面試題
A:字符串一旦被賦值就不能改變。
注意:字符串的值不能改變,沒有說引用變量不能改變。
B:面試題:
a:String s1 = new String("hello")和String s2 = "hello"的區別。

s1是一個對象,存在於堆中,能夠調用string類中的方法;s2是是一個字符串常量,不能夠操做string類中的方法。
b:請寫出結果:
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1==s2);//false地址值不同
System.out.println(s1.equals(s2));//true內容同樣
String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3==s4);//false不具可比性
System.out.println(s3.equals(s4));//true內容同樣
String s5 = "hello";
String s6 = "hello";
System.out.println(s5==s6);//true變量值同樣
System.out.println(s5.equals(s6));//true
(4)成員方法
A:判斷功能
boolean equals(Object obj):判斷字符串的內容是否相同,區分大小寫。boolean equals(obj)
boolean equalsIgnoreCase(String str):判斷字符串的內容是否相同,不區分大小寫。boolean equalsIgnnoreCase(str)
boolean contains(String str):判斷字符串對象是否包含給定的字符串。boolean contains(str)
boolean startsWith(String str):判斷字符串對象是否以給定的字符串開始。boolean startWith(str)
boolean endsWith(String str):判斷字符串對象是否以給定的字符串結束。boolean endWith(str)
boolean isEmpty():判斷字符串對象是否爲空,數據是否爲空。boolean isEmpty()
B:獲取功能
int length():獲取字符串的長度。int length()
char charAt(int index):返回字符串中給定索引處的字符。char charAt(index)
int indexOf(char ch):返回指定字符在此字符串中第一次出現的索引。int indexOf(ch)
int indexOf(String str):返回指定字符串在此字符串中第一次出現的索引。int indexOf(str)
int indexOf(int ch,int fromIndex):返回在此字符串中第一次出現指定字符的索引,從指定的索引開始搜索。
int indexOf(String str,int fromIndex):返回在此字符串中第一次出現指定字符串的索引,從指定的索引開始搜索。
String substring(int start):截取字符串,返回從指定位置開始截取後面的字符串。string substring(start)
String substring(int start,int end):截取字符串,返回從指定位置開始到指定位置結束截取後的字符串。
C:轉換功能
byte[] getBytes():把字符串轉換成字節數組。byte[] getBytes()
char[] toCharArray():把字符串轉換成字符數組。char[] toCharArray()
static String copyValueOf(char[] chs):把字符數組轉換成字符串。
static String valueOf(char[] chs):把字符數組轉換成字符串。String valueOf(chs)
static String valueOf(int i):把int(基本類型)轉換成字符串。String valueOf(int)
String toLowerCase():把字符串變成小寫。String toLowerCase()
String toUpperCase():把字符串變成大寫。String toUpperCase()
String concat(String str):拼接字符串。String concat(str)
D:其餘功能
a:替換功能
String replace(char oldChar,char newChar):用新的字符去替換指定的舊字符。replace(oldCh,newCh)
String replace(String oldString,String newString): 用新的字符串去替換指定的舊字符串。
b:切割功能
String[] split(String regex):按照規定的格式切割字符串成字符串數組。string[] split(regex)//傳入正則表達式
c:去除兩端空格功能
String trim():去除字符串兩端空格。string trim()
d:字典順序比較功能
int compareTo(String str):按字典順序(Unicode 編碼順序)若是第一個相同比較第二個依次類推。
int compareToIgnoreCase(String str) :按字典順序( Unicode 編碼順序)若是第一個相同比較第二個依次類推不區分大小寫
(5)案例
A:模擬用戶登陸(用到了判斷equals 功能,若是有的用戶名不區分大小寫還能夠用equalsIgnorCase)
String username = "admin";
String password = "admin";
// 三次機會
for (int x = 0; x < 3; x++) {
// x 0,1,2
// 鍵盤錄入數據:用戶名和密碼。
Scanner sc = new Scanner(System.in);
System.out.println("請輸入用戶名: ");
String name = sc.nextLine();
System.out.println("請輸入密碼: ");
String pwd = sc.nextLine();
// 把數據進行比較。
if (username.equals(name) && password.equals(pwd)) {
System.out.println("恭喜你,登陸成功");
// 引入曾經的猜數字小遊戲。
break;
} else {
if ((2 - x) == 0) {
System.out.println("帳號被鎖定,請與站長聯繫");
} else {
// 2,1,0
System.out.println("登陸失敗,你還有" + (2 - x) + "次機會");
}
}
}
B:字符串遍歷(用到了charAt 功能)
for (int x = 0; x < s.length(); x++) {
char ch = s.charAt(x);
System.out.println(ch);
}
C:統計字符串中大寫、小寫、數字字符出現的次數(用到了charAt 功能)
String s = "Hello12345World";
// 定義三個統計變量
int bigCount = 0;
int smallCount = 0;
int numberCount = 0;
// 遍歷字符串。
for (int x = 0; x < s.length(); x++) {
char ch = s.charAt(x);
// 判斷是屬於哪一種範圍
if (ch >= 'A' && ch <= 'Z') {
bigCount++;
} else if (ch >= 'a' && ch <= 'z') {
smallCount++;
} else if (ch >= '0' && ch <= '9') {
numberCount++;
}
}
D:把字符串的首字母大寫,其餘小寫(用到了截取、鏈接、轉大小寫功能)
String str2 =str.substring(0,1).toUpperCase().concat(str.substring(1).toLowerCase());
E:大串中小串出現的次數(用到了截取、indexOf 功能)
public int getCount(String maxString, String minString) {
// 定義統計變量
int count = 0;
// 在大串中查找小串一次
int index = 0;
// 若是返回值不是-1,說明小串在大串中是存在的。
// 判斷
while ((index = maxString.indexOf(minString)) != -1) {小串在大串中第一次出現的索引
// 統計變量++
count++;
// 把查找過的數據給截取掉,從新賦值給大串
maxString = maxString.substring(index + minString.length());
}
return count;
}
F:學習indexOf 過程當中發現contains()的底層就是用的indexOf()
public boolean contains(CharSequence s) {
return indexOf(s.toString()) > -1;
}

part13 經常使用API:Arrays、system、stringbuffer、interger

1:數組操做(理解原理,並要求會寫該算法的代碼)
1):冒泡排序原理:相鄰元素兩兩比較,大的日後走,第一次完畢後最大值就在最大索引處。(升序)
2):冒泡排序代碼
public static void bubbleSort(int[] arr) {
// 外循環控制次數
for (int x = 0; x < arr.length - 1; x++) {
// 內循環控制每一次的比較過程
/*
* 第一次,全部元素都參與比較,也就是0 個元素不參與。
* 第二次,有1 個元素不用參與。
* 第三次,有2 個元素不用參與。...
*/
// -1 是爲了防止索引越界
// -x 是爲了減小比較的次數
for (int y = 0; y < arr.length - 1 - x; y++) {
if (arr[y] > arr[y + 1]) {
// 數據交換
int temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;
}
}
}
}
3):查找
--普通查找:數組無序
--二分查找(折半查找):數組有序
4):二分查找的代碼:根據值查所在索引
public static int getIndex(int[] arr,int value)
{
int maxIndex = arr.length-1;
int minIndex = 0;
int midIndex = (maxIndex+minIndex)/2;
while(arr[midIndex]!=value){
if(arr[midIndex]>value)
{
maxIndex = midIndex - 1;
}
else if(arr[midIndex]<value)
{
minIndex = midIndex + 1;
}
if(minIndex > maxIndex)
{
return -1;
}
midIndex = (maxIndex+minIndex)/2;
}
return midIndex;
}
2:Arrays 工具類的使用
(1)Arrays 是針對數組操做的工具類。
(2)成員方法:
public static String toString(數組):把數組變成字符串。String toString(arr[])
public static void sort(數組):對數組進行排序(升序) 。void sort(arr[])
public static int binarySearch(int[] arr,int value):二分查找int binarySerch(arr[],value)
3:System 的方法(掌握)
(1)系統類提供了靜態的變量和方法供咱們使用。
(2)成員方法:
public static void exit(int value):退出jvm,非0 表示異常退出。void exit(value)
public static long currentTimeMillis():返回當前系統時間的毫秒值。(通常用來測試一個程序執行的快慢)
返回的是和1970 年1 月1 日午夜之間的時間差
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,intlength):從指定源數組中複製一個數組, 複製從指定的位置開始,到目標數組的指定位置結束。
4:StringBuffer:便可變長的String
(1)字符個數能夠發生改變的字符串類,字符串緩衝區類。
(2)構造方法:
A:StringBuffer():默認容量16
B:StringBuffer(int capacity):指定容量
C:StringBuffer(String str):把字符串轉換成StringBuffer
(3)成員方法:
A:添加功能
public StringBuffer append(int i):在末尾追加元素。StringBuffer append(int)
public StringBuffer insert(int index,int i):在指定位置添加元素。StringBuffer insert(index,int)
B:刪除功能
StringBuffer deleteCharAt(int index):刪除指定位置字符。StringBuffer deleteCharAt(index)
StringBuffer delete(int start, int end):刪除指定開始位置和結束位置間的字符。StringBuffer delete(start,end)
C:替換功能
StringBuffer replace(int start, int end, String str):把開始到結束位置的字符用一個新的字符串給替換。
D:截取功能
String substring(int start):從指定位置到末尾截取。String substring(start)
String substring(int start, int end): 從指定位置到結束位置截取。
E:反轉功能
StringBuffer reverse():字符串反轉。StringBuffer reverse()
(4)案例:
字符串反轉。
StringBuffer sb = new StringBuffer("abc");
sb.reverse();
String result = new String(sb);
System.out.println(result);//cba
5:基本類型包裝類(掌握)
(1)基本類型的數據咱們只能使用值,不能作更多的操做。爲了方便咱們操做java 就把每種基本類型進行了包裝,提供方法供咱們使用。
(2)基本類型和包裝類的對應關係
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
(3)Integer 構造方法
A:Integer i = new Integer(int num);
B:Integer i = new Integer(String s);
注意:s 必須是一個由數字字符組成的字符串。
(4)String 和int 類型的轉換
A:String -- int:parseInt(str)
Integer:public static int parseInt(String s)
B:int -- String:toString(int)/valueOf(int)
Integer:public static String toString(int i)
String:public static String valueOf(int i)
(5)JDK5 之後的新特性
A:自動裝箱基本類型--引用類型
B:自動拆箱引用類型--基本類型
舉例:
Integer i = 100;// 默認至關於new Integer(100)
i += 200;// 等價於i = new Integer(i.intValue()+200);
//由於i += 200 底層調用的是intValue()方法, 因此咱們要加一層判斷,防止報空指針異常
if (i != null) {
i += 200;
System.out.println(i);
}
(6)面試題:byte 常量池
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2);// false
System.out.println(i1.equals(i2));// true
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4);// false
System.out.println(i3.equals(i4));// true
Integer i5 = 128;
Integer i6 = 128;
System.out.println(i5 == i6);// false
System.out.println(i5.equals(i6));// true
//byte 常量池。byte 範圍內的值直接賦值給Integer,是從常量池裏面獲取的。
Integer i7 = 127;
Integer i8 = 127;
System.out.println(i7 == i8);// true
System.out.println(i7.equals(i8));// true
(7)案例:
把字符串中的數字字符排序。
需求:"23 98 16 38 42"
結果:"16 23 38 42 98"
代碼:
String s = "23 98 71 54 60";
// 字符串轉字符串數組
String[] strArray = s.split(" ");
// 字符串數組轉int 數組(數字才能夠比較大小,字符無法比較大小)
int[] arr = new int[strArray.length];//此時尚爲空數組 
// 循環遍歷對arr數組依次賦值
for (int x = 0; x < arr.length; x++) {
arr[x] = Integer.parseInt(strArray[x]);
}
//int[]數組排序
Arrays.sort(arr);
//把排序後的int[] -- String
StringBuffer sb = new StringBuffer();
for(int x=0; x<arr.length ;x++){
sb.append(arr[x]).append(" ");//在sb字符串末尾追加元素
}
String result = sb.toString().trim();//去除字符串兩端空格
System.out.println(result);

**:關於學習方法:
A:常常回顧,每次回顧都會有新的發現
B:常常練習
C:概括總結錯誤
D:自學習慣鍛鍊本身獨立思考問題的能力,用代碼去實現你的思路。
**:面試題:隨機給出一個數組,要求把越靠近50 的數往左排;
public static void main(String[] args) {
int[] arr = { 1, 2, 4, 7, 9, 12, 2, 3, 4, 89, 100, 105, 88, 50, 49, 48,
48, 47, 99, 60, 40, 30, 70 };
// int[] arr= {1,4,5,7,8,22,44};
arr = sort50(arr);
System.out.println(Arrays.toString(arr));
}
public static int[] sort50(int[] arr) {//靠近50的排序方法
// 從小到大排
Arrays.sort(arr);
/*
* 若是數組裏面全部的數都大於50就返回原數組
*/
if (arr[1] >= 50) {
return arr;
/*
* 若是數組裏面全部的數都小於50,
*/
} else if (arr[arr.length - 1] <= 50) {
int[] arrtemp = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
arrtemp[arr.length - 1 - i] = arr[i];
}
return arrtemp;
/*
* 若是數組裏面有大於50 的也有小於50 的
*/
} else {
// 外循環控制次數
for (int x = 0; x < arr.length - 1; x++) {
// 內循環控制每一次的比較過程
/*
* 第一次, 全部元素都參與比較, 也就是0 個元素不參與。第二次,有1
個元素不用參與。第三次, 有2 個元素不用參與。...
*/
// -1 是爲了防止索引越界
// -x 是爲了減小比較的次數
for (int y = 0; y < arr.length - 1 - x; y++) {
if (Math.abs(arr[y] - 50) > Math.abs(arr[y + 1] - 50)) {
// 數據交換
int temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;
}
}
}
/*// 選擇排序法
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (Math.abs(arr[i] - 50) > Math.abs(arr[j] - 50)) {
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}*/
}
return arr;
}

part14 經常使用API:date、對象數組和綜合案例

1:實際開發中經常遇處處理時間和日期的狀況,Java中提供了date類來處理。
2:Date
(1)日期類。
構造方法:
Date():默認指當前系統時間。
Date(long time):根據給定的毫秒值生成一個時間。
(2)完成以下操做(日期和毫秒值的轉換)
Date --> long:Date.getTime()
Date d = new Date();
long time = d.getTime();
long –> Date:Date的有參構造或Date.setTime()
long time = ???;
Date d = new Date(time);
或D
ate d2 = new Date();
d2.setTime(time);
(3)DateFormat 類(日期和字符串的轉換)
String –> Date:日期格式對象.parse(string)
public Date parse(String source)
注意:若是是字符串到日期,你指定的格式必須和字符串的格式匹配。
2013-12-12
yyyy-MM-dd
2013/11/11
yyyy/MM/dd
Date –> String:日期格式對象 .format(date)
public final String format(Date date)
須要本身指定格式,常見的格式:
yyyy 年MM 月dd 日HH:mm:ss
yyyy 年MM 月dd 日
HH:mm:ss
yyyy-MM-dd HH:mm:ss
2: Calendar
(1)Calendar 是日曆類,能夠獲取任意指定日曆值,而後自由組合。
Calendar 是抽象類不能實例化,可是他提供了獲取其實例的方法
Calendar c = Calendar.getInstance();// 多態
(2)成員方法:
get(日曆字段):根據給定的日曆字段獲取值
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int date = c.get(Calendar.DATE);
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
int second = c.get(Calendar.SECOND);
String s = year + "年" + (month + 1) + "月" + date + "日" + " " + hour
+ ":" + minute + ":" + ((second>9)?second:"0"+second);
set(年,月,日):給日曆設定指定的年, 月, 日
add(日曆字段,值):給指定的日曆字段添加或者減去給定的值。取決於值的正負。
(3)案例:請說出任意一年的2 月份是多少天。
Calendar c = Calendar.getInstance();
Scanner sc = new Scanner(System.in);
int year = sc.nextInt();
c.set(year, 3, 1);// 把日期設置爲2013 年3 月1 日
c.add(Calendar.DATE, -1);// 把日期往前推1 日
System.out.println(c.get(Calendar.DATE));
3:對象數組
用以放置對象的數組
4:案例:對象數組改進登錄註冊
UserDao:操做接口
UserDaoImpl:操做類實現操做接口
User:存儲學生數據的對象(能夠存儲用戶名, 密碼, 郵箱等等)
UserTest:測試類
代碼: 只給你們寫一個UserDaoImpl 和UserTest,其餘的比較簡單
/**
* 用戶操做實現類
**
如何實現呢? 若是是註冊一個用戶用User 保存便可。可是註冊確定不止一個用戶, 因此咱們得想一想用什麼存儲?
目前咱們學過的可以存儲的:對象,對象數組。經過分析最終選擇對象數組。可是這樣作有問題:對象數組須要定義數組, 定義數組就得知道長度。但是沒法肯定數組長度。因此對象數組不夠好。最終選擇集合。不過集合還沒學呢, 因此如今只能使用對象數組。本身給一個固定長度: 5
*/
public class UserDaoImpl implements UserDao {
// 定義成員變量的數組
private static User[] users = new User[5];//用戶數組
private static int index = 0;
@Override
public boolean isLogin(String username, String password) {//登陸
/*
* 遍歷數組,獲取到每個對象,而後再拿對象的用戶名和密碼和傳遞過來的用戶名和密碼進行比較
*/
boolean flag = false;
for (int x = 0; x < users.length; x++) {
User user = users[x];
// 判斷用戶是否爲null
if (user != null) {

//對比穿過來的用戶名和密碼
if (user.getUsername().equals(username) && user.getPassword().equals(password)) {
flag = true;
break;
}
}
}
return flag;
}
@Override
public void regist(User user) {//註冊
users[index++] = user;
}
}
----------------------------------------------------------------
import java.util.Scanner;
public class UserTest {
public static void main(String[] args) {
while (true) {
System.out.println("歡迎來到XXX");
System.out.println("1:登陸");
System.out.println("2:註冊");
System.out.println("3:退出");
System.out.println("請選擇: ");
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
switch (line) {
case "1":
System.out.println("歡迎來到登陸界面");
System.out.println("請輸入用戶名: ");
String username = sc.nextLine();
System.out.println("請輸入密碼: ");
String password = sc.nextLine();
UserDao ud = new UserDaoImpl();// 多態用法
// 具體類用法
UserDaoImpl udi = new UserDaoImpl();
boolean flag = udi.isLogin(username, password);
if (flag) {
System.out.println("開始玩遊戲吧");
System.exit(0);
} else {
System.out.println("登陸失敗,返回主界面");
}
break;
case "2":
System.out.println("歡迎來到註冊界面");
// 鍵盤錄入用戶信息
System.out.println("請輸入用戶名: ");
String newUsername = sc.nextLine();
System.out.println("請輸入密碼: ");
String newPassword = sc.nextLine();
System.out.println("請輸入郵箱: ");
String newEmail = sc.nextLine();
System.out.println("請輸入電話: ");
String newPhone = sc.nextLine();
// 把數據用對象進行封裝
User user = new User();
user.setUsername(newUsername);
user.setPassword(newPassword);
user.setEmail(newEmail);
user.setPhone(newPhone);
// 建立用戶操做類對象
UserDaoImpl newUdi = new UserDaoImpl();
// 調用註冊方法
newUdi.regist(user);
System.out.println("註冊成功");
break;
case "3":
// System.out.println("謝謝你的使用");
// System.exit(0);
// break;
default:
System.out.println("謝謝你的使用");
System.exit(0);
break;
}
}
}
}

part15 集合:cllection和list接口

1: 集合(理解)
(1)java 是一種面嚮對象語言,若是要針對多個對象進行操做就必須對多個對象進行存儲,而對多個元素進行存儲,數組有弊端---長度固定,數組將不能知足變化的要求,因此java 就提供了集合。
(2)集合的特色:
一、長度能夠發生改變
二、只能存儲對象
三、能夠存儲多種類型對象(通常存儲的仍是同一種)
(3)集合和數組的區別
一、長度問題
數組固定;集合可變
二、存儲元素問題
數組能夠是基本類型,也能夠是引用類型;集合只能是引用類型。
三、是否同一類型
數組元素類型一致;集合元素類型能夠不一致。
(4)集合體系的由來
集合是存儲多個元素的容器,可是因爲數據結構不同,java 就提供了多種集合類。而這多種集合類有共性的功能,因此經過不斷的向上抽取最終造成了集合體系無標題
結構。
數據結構:數據存儲的方式。
程序= 算法+ 數據結構
(5)如何學習和使用一個繼承體系呢?
學習頂層:由於頂層定義的是共性內容。
使用底層:由於底層纔是具體的實現。
2: Collection 的功能(掌握)
(1)Collection 的功能
一、添加功能:add()
boolean add(Object obj):向集合中添加一個元素。
boolean addAll(Collection c):向集合中添加一個集合的元素。
二、刪除功能:clear()/remove()
void clear():刪除集合中全部的元素。
boolean remove(Object obj):刪除集合中指定的元素。
boolean removeAll(Collection c):刪除集合中指定的集合元素,只要有數據刪除,則返回true 。
三、判斷功能:isEmpty()/contains()
boolean isEmpty():判斷集合是否爲空。
boolean contains(Object obj):判斷集合是否包含指定的元素。
boolean containsAll(Collection c):判斷集合是否包含指定的集合中的元素。只有全部數據包含了才返回true 。
四、遍歷功能:iterator迭代器
Iterator iterator():迭代器。
hasNext():判斷是否還有元素
next():獲取下一個元素
五、長度功能:size()
int size():得到集合的元素個數。
六、交集功能:retainAlll()
boolean retainAll(Collection c):判斷集合中是否有相同的元素。若是有兩個集合A 和B ,A 對B 作交集,A 集合保存的是交集元素,B 集合不發生改變,返回值表示的是A 集合是否發生過改變。
七、轉換功能:toArray()
Object[] toArray():把集合變成數組。
(2)迭代器的使用
一、使用步驟
a、經過集合對象獲取迭代器對象。
b、經過迭代器對象判斷。
c、經過迭代器對象獲取。
二、迭代器原理
因爲多種集合的數據結構不同因此存儲方式不同,因此取出方式也不同。此時就把判斷和獲取功能定義在了一個接口中,未來遍歷哪一種集合的時候只要該集合內部實現這個接口便可。
(3)集合的常見使用步驟:
一、建立集合對象
二、建立元素對象
三、把元素添加到集合中
四、遍歷集合
a、經過集合對象獲取迭代器對象。
b、經過迭代器對象判斷。
c、經過迭代器對象獲取。
(4)Collection 存儲字符串和自定義對象並遍歷。
一、存儲字符串
Collection c = new ArrayList();//建立集合
//String s = "hello";
//c.add(s);
c.add("hello");//添加元素
c.add("world");
c.add("java");
Iterator it = c.iterator();//迭代器進行遍歷
while(it.hasNext())
{
String s = (String)it.next();
System.out.println(s);
}
二、存儲自定義對象
Collection c=new ArrayList();//定義集合
Student s1=new Student("林青霞",26);//定義元素
c.add("s1");//添加元素
Iterator it=c.iterator();//迭代器遍歷
while(it.hasNext())
{
String s=(String)it.next();
System.out.println(s);
}
3: List 的特有功能
(1)List 的特色
List 是Collection 接口下的一個子接口
特色:元素有序可重複。
Set 也是Collection 接口下的一個子接口
特色:元素無序惟一。
(1)List 的特有功能
一、添加功能:add(index,obj)
void add(int index,Object obj): 在指定位置添加元素。
二、刪除功能:remove(index)
Object remove(int index): 根據指定索引刪除元素,並把刪除的元素返回
三、修改功能:set(index,obj)
Object set(int index,Object obj):把指定索引位置的元素修改成指定的值,返回修改前的值。
四、獲取功能:get(index)/indexOf(obj)/ListIterator--list迭代器
Object get(int index): 獲取指定位置的元素
int indexOf(Object obj): 返回指定元素在集合中第一次出現的索引。
ListIterator listIterator():list迭代器
五、截取功能:subList(fromIndex,toIndex)
List subList( int fromIndex, int toIndex )截取集合。
(2)List 的遍歷方式
一、Iterator 迭代器
二、ListIterator 迭代器(僅做了解)
三、普通for+get()
(3)ListIterator 迭代器
ConcurrentModificationException 併發修改異常
ConcurrentModificationException
①:爲何出現這個異常:由於咱們在用迭代器遍歷的時候,經過集合對元素進行了操做
②:如何解決呢:
A:經過迭代器遍歷的時候,用迭代器進行操做集合元素ListIterator
B:普通for 循環遍歷集合的時候,經過集合對元素進行操做

part16 集合:List實現類、泛型

1:常見的數據結構
棧,隊列,數組,鏈表
棧:先進後出,類比水桶
隊列:先進先出,類比出水管
數組:查詢快(含有索引),增刪慢
鏈表:查詢慢(沒有索引),增刪快

擴展知識:

image
2: List 的三個兒子
(1)List 的三個兒子特色:
List
|--ArrayList
底層數據結構是數組,查詢快,增刪慢
線程不安全,效率高
|--Vector
底層數據結構是數組,查詢快,增刪慢
線程安全,效率低
|--LinkedList
底層數據結構是鏈表,查詢慢,增刪快
線程不安全,效率高
(2)案例:ArrayList 存儲自定義對象去重複
需求:ArrayList 若是存儲的是學生,那麼怎麼去除重複元素呢?
問題:如何知道學生是重複的?
需求:若是學生的姓名和年齡相同,我就認爲是同一個學生,即重複值。
問題分析:經過簡單分析咱們估計是判斷那裏出問題了。
看判斷的方法。而咱們又知道,判斷的方法是API 提供的不是本身寫的。因此看源碼,經過看原碼發現,底層依賴的是equals()方法。因爲學生類中並無equals()方法,因此默認用的是Object 的方法。而Object 類的方法,默認比較的是地址值。因爲學生對象都是new 出來的地址值確定不同樣,因此從這個角度考慮結論是正確的。可是不符合咱們的需求。怎麼辦呢?此時要重寫equals()方法,讓它按照咱們的需求來比較。
代碼:
public static void main(String[] args) {
ArrayList array = new ArrayList();
Student s1 = new Student("鄭成功", 40);
Student s2 = new Student("戚繼光", 50);
Student s3 = new Student("戚繼光", 50);
Student s4 = new Student("岳飛", 36);
Student s5 = new Student("岳飛", 40);
Student s6 = new Student("林則徐", 30);
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
array.add(s5);
array.add(s6);
// 建立新集合
ArrayList array2 = new ArrayList();
// 遍歷舊集合,獲取到每個元素
Iterator it = array.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
// 在新集合中判斷, 看是否存在這個元素
if (!array2.contains(s)) {
// 若是s 不再array2 中存在就添加
array2.add(s);
}
}
// array2 就是沒有重複元素的集合。
// 遍歷array2
for (int x = 0; x < array2.size(); x++) {
Student s = (Student) array2.get(x);
System.out.println(s.getName() + "***" + s.getAge());
}
}
(3):Vector 的特有功能
A: 添加功能。
void addElement( Object obj )  
B: 獲取功能。
public Object elementAt( int index )
public Enumeration elements()//枚舉:用於存儲「穩定的」數據集
類Enumeration 裏邊有兩個方法。(相似於迭代器)
boolean hasMoreElements()
Object nextElement()
public int size()
(4):LinkedList 的特有功能
A: 添加功能
void addFirst( Object o ):將指定元素插入此列表的開頭。
void addLast( Object o ):將指定元素添加到此列表的結尾。
B: 獲取功能
Object getFirst()
Object getLast()
C: 刪除功能
Object removeFirst()
Object removeLast()
(5):面試題:用LinkedList 模擬棧數據結構
package cn.itcast_02;
A:第一步,自定義棧集合的類。
import java.util.LinkedList;
//自定義棧集合
public class MyStack {
//經過LinkedList 模擬棧數據結構
private LinkedList list;
public MyStack()
{
list = new LinkedList();
}
public void add(Object obj)
{
list.addFirst(obj);
}
public Object get(int index)
{
return list.get(index);
}
public int size()
{
return list.size();
}
}
B: 在測試類中測試。
package cn.itcast_02;
public class MyStackTest {
public static void main(String[] args) {
MyStack ms = new MyStack();
ms.add("hello");
ms.add("world");
ms.add("java");
for (int x = 0; x < ms.size(); x++) {
String s = (String) ms.get(x);
System.out.println(s);
}
}
}
(6)到底使用誰根據需求看
是否要安全:
是:Vector
否:ArrayList,LinkedList
查詢多:ArrayList
增刪多:LinkedList
若是什麼都不知道用ArrayList 。
3: 泛型(理解)
(1)泛型是一種把明確類型的工做放在了建立對象或者調用方法時候纔去明確的特殊的類型。
(2)格式:<數據類型>
(3)好處:
A:解決了黃色警告線問題
B:把運行期間的轉換異常給提早到了編譯期間
C:優化了程序設計,不須要作強制類型轉換了
1):泛型類
需求:我能不能不用重載方法,就能夠實現同一個方法輸出不同類型的數據呢?
package cn.itcast_03;
//尖括號中的QQ 表明的是任意類型,QQ 也能夠用其餘任意字母代替(自定義)
public class Tool<QQ> {
//這裏的QQ 必須和上邊尖括號中的名字同樣,qq 是變量名,能夠自定義
public void show(QQ qq)
{
//輸出QQ 類型的變量qq
System.out.println(qq);
}
}
2):泛型方法
爲了保證方法傳遞不同的參數,就在類上明確了類型。這樣的話,它要是可以在調用方法的時候,纔去明確類型該有多好呢
public class Tool
{
public <BYD> void show( BYD byd )
{
System.out.println( byd );
}
}
3):泛型接口
A:定義Inter接口的代碼。
package cn.itcast_03;
public interface Inter<BMW> {
public abstract void show(BMW bmw);
}
B:接口Inter 的實現類InterImpl 中的代碼。
package cn.itcast_03;
public class InterImpl<BMW> implements Inter<BMW> {
@Override
public void show(BMW bmw) {
System.out.println(bmw);
}
4:加強for 循環
(1)格式:
for(數組或者Collection 集合的元素類型 變量: 數組或者Collection 集合的對象)
{
   直接使用變量便可。
}
(2)好處:
方便了數組和Collection 集合的遍歷。
(3)注意(注意):
A:加強for 是用來替代迭代器的。其底層就是調用的迭代器
B:不要在用加強for 遍歷集合的時候,用集合對集合自己進行修改。
(4)遍歷List 集合體系三種方式
1):迭代器
2):普通for+get
3):加強for(實際開發時時候用)
Collection 集合遍歷兩種方式
1):迭代器
3):加強for(工做時候用)

part17 集合:set實現類

面試題:用集合改進登錄註冊案例
本次用集合改進「登錄註冊」,僅僅是把包cn.itcast.dao.impl中的類UserDaoImpl 中的內容給修改了下。
public class UserDaoImpl implements UserDao {
//建立集合對象
private static ArrayList<User> array = new ArrayList<User>();
@Override
public boolean isLogin(String username, String password) {
// 遍歷數組,獲取到每個對象,
// 而後再拿對象的用戶名和密碼和傳遞過來的用戶名和密碼進行比較
boolean flag = false;
//遍歷集合獲取每個用戶,若是存在就修改標記爲true
for(User u : array)
{
if(u.getUsername().equals(username) &&
u.getPassword().equals(password))
{
flag = true;
break;
}
}
return flag;
}
@Override
public void regist(User user) {
//將該用戶添加到集合中
array.add(user);
}
}
1:Set(掌握)
(1)Set 的特色:
元素無序惟一。(注意和List 的對比:元素有序可重複。)
注意:這裏的順序是指存儲和取出順序。
2:HashSet:保證惟一的方法---hashCode()和equals()
(1)HashSet:不保證元素的迭代順序,且不保證該順序恆久不變。
(2)怎麼保證的呢?
HashSet 底層數據結構是哈希表。它依賴兩個方法:hashCode()和equals()
順序:
首先,判斷hashCode()值是否相同。
相同:繼續走equals()方法,根據其返回值:
true:說明元素重複,不添加到集合。
false:說明元素不重複,添加到集合。
不同:直接添加到集合。
(3)重寫hashCode()和equals()方法:
hashCode():
把對象的全部成員變量值相加便可。
若是是基本類型就加值。若是是引用類型就加哈希值。
public int hashCode()
{
return this.name.hashCode() + this.age + this.sex +this.score ;
}
equals():
A:this==obj
B:!(obj instanceof Student)
C:全部成員變量的值比較,基本類型用==,引用類型用equals()
3:TreeSet:保證惟一的方法----實現comparable接口或comparator比較器接口
(1)TreeSet:根據構造方法的不用,選擇使用天然排序或者比較器排序。按照實際的需求可對元素進行排序而且保證惟一。
(2)如何保證元素惟一的:
排序:底層結構是二叉樹,按照樹節點進行存儲和取出。
兩種實現:
A:天然排序(元素具有比較性):TreeSet 的無參構造,要求對象所屬的類實現Comparable 接口。
public int compareTo( Studetn s )
{
//需求是比較年齡
int num = this.age - s.age ;
//因爲對象有多個成員變量,不能根據其中的某一個決定其餘的。
//當某一個相同的時候還須要判斷其餘的是不是也是相同的。
int num2 = ( num == 0 ) ? ( this.name.compareTo( s.name ) ) :
num ;
return num2;
}
B:比較器排序(集合具有比較性):TreeSet 的帶參構造,要求構造方法接收一個實現了Comparator 接口的對象。
TreeSet<Student> ts = new TreeSet<Student> ( new
Comparator<Student>
{
@Override
public int compare ( Student s1 , Student s2)
{
//按照年齡排序從小到大
int num = s1.getAge() - s2.getAge();
//次要條件
int num2 = ( num == 0 ) ? (
s1.getName().compareTo(s2.getName()) ) : num;
return num2;
}
} );
//建立元素對象
Student s1 = new Student(「張三」, 24);
Student s2 = new Student(「李四」, 30);
Student s1 = new 。。。。。。
//添加元素
ts.add(s1);
ts.add(s2);
...........
for( Student s : ts )
{
System.out.println(s.getName() + "*****" + s.getAge());
}
惟一:根據返回值是否爲0 。
注意:若是同時有兩種方案以比較器爲主。
(3)案例:TreeSet 存儲自定義對象按照姓名長度排序
public int compareTo( Studetn s )
{
//需求是比較姓名的長度
int num = this.name.length() - s.name.length() ;
//不少時候,別人給咱們的需求其實只是一個主要需求
//還有不少的次要需求是須要咱們本身進行分析的。
//比較姓名的內容
int num2 = ( num == 0 ) ? ( this.name.compareTo( s.name ) ) : num ;
//繼續分析,姓名長度和內容都相同的狀況下,年齡還可能不同樣
//因此當姓名長度和內容都相同的時候,再比較下年齡
int num3 = ( num2 == 0 ) ? ( this.age - s.age ) : num3 ;
return num3;
}
(4)原理:二叉樹保證元素惟一排序
A:第一個添加的數據做爲根節點。
B:從第二個開始,
每個數據從根節點開始比較,
若是大了往右邊放,若是小了往左邊放,若是相同則替換。
C:從根節點開始,獲取數據的規則:按照每一個數據的:左,中,右原則。
4: Collection 體現的集合總結
Collection
|—List:元素有序可重複
   |—ArrayList:底層數據結構是數組,查詢快增刪慢
   線程不安全,效率高。
   |—LinkedList:底層數據結構是鏈表,查詢慢增刪快
   線程不安全,效率高。
   |—Vector:底層數據結構是數組,查詢快增刪慢
   線程安全,效率低。
|—Set:元素無序,惟一
   |—HashSet:底層數據結構是哈希表。
   保證元素惟一性:依賴兩個方法---hashCode()和equals() 。
   |—TreeSet:底層數據結構是二叉樹。
   保證元素惟一: 根據返回值是不是0,判斷元素是否重複。
   排序有兩種方案:
      元素具有比較性實現Comparable 接口
      集合具有比較性實現Comparator 接口
5: 在集合中的數據結構問題
ArrayXxx:底層數據結構是數組,查詢快增刪慢
LinkedXxx:底層數據結構是鏈表,查詢慢增刪快
HashXxx:底層數據結構是哈希表,跟兩個有關:hashCode()和equals()
TreeXxx:底層數據結構是二叉樹:兩種排序方式:Comparable 接口天然排序和Comparator 接口比較器排序
6: 何時,使用哪一種Collection 集合。
元素惟一嗎?
惟一:Set
須要排序嗎?
  須要:TreeSet
  不須要:HashSet
  不知道:用HashSet 。
不惟一:List
須要安全碼?
  須要:Vector
  不須要:ArrayList 和LinkedList
     查詢多:ArrayList
     增刪多;LinkedList
     不知道,用ArrayList 。
7:Collections工具類
(1)Collections 是針對Collection 集合操做的工具類。
public static void sort ( List list ):排序。
public static <T> int binarySearch( List list, T key ):二分查找。
public static void reverse( List list ):反轉。
public static T max( Collection coll ):最大值。
public static void shuffle( List list ):隨機置換(至關於「洗牌」)
(2)面試題:
Collection 和Collections 的區別?
Collection:是Collection 集合的頂層接口,定義了Collection 集合的共性方法。
Collections:是一個collection集合的工具類,定義了針對Collection 集合操做的功能,有排序、查找、反轉等。
(3)案例:鬥地主洗牌發牌小遊戲
public static void main(String[] args) {
// 買牌
// 表示花色的數組
String[] colors = { "黑桃", "紅桃", "梅花", "方塊" };
// 表示點數的數組
String[] numbers = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10","J", "Q", "K" };
// 造一個牌盒
ArrayList<String> array = new ArrayList<String>();
array.add("大王");
array.add("小王");
// 循環裝牌
for (String c : colors) {
for (String n : numbers) {
array.add(c.concat(n));
}
}
// 顯示全部牌
// System.out.println(array);
// 洗牌
Collections.shuffle(array);
// 顯示全部牌
// System.out.println(array);
// 發牌
ArrayList<String> linString = new ArrayList<String>();
ArrayList<String> zhouString = new ArrayList<String>();
ArrayList<String> meString = new ArrayList<String>();
// 用普通for
for (int x = 0; x < array.size() - 3; x++) {
if (x % 3 == 0) {
linString.add(array.get(x));
} else if (x % 3 == 1) {
zhouString.add(array.get(x));
} else if (x % 3 == 2) {
meString.add(array.get(x));
}
}
// 看牌
System.out.println("linString:" + linString);
System.out.println("zhouString:" + zhouString);
System.out.println("meString:" + meString);
// 看底牌
for (int x = array.size() - 3; x < array.size(); x++) {
System.out.print(array.get(x) + " ");
}
}

part18 集合:Map

1:Map
(1)Map 是一個鍵值對形式的集合,它的元素都是有鍵和值組成。
(2)Map 和Collection 的區別?(面試題)
A:Map 是由鍵值對組成的集合,Map 的鍵(key)是惟一的,值(value)能夠重複。
B:Collection 是有單列數據組成的集合,它的兒子List 是能夠重複的,Set 是惟一的。
(3)HashMap 和Hashtable 的區別?(面試題)
HashMap:線程不安全效率高,容許null 鍵和值。
Hashtable:線程安全效率低,不容許null 鍵和值。
(4)Map 的功能:
A:添加功能
V put(K key, V value) 當key 在集合中不存在時添加元素;當key 在集合中存在的時候替換元素。
B:判斷功能
boolean containsValue( Object value ) 判斷指定的值是否在集合中存在。
boolean isEmpty() 判斷集合是否爲空。
C:刪除功能
void clear() 清除全部鍵值對數據。
V remove( Object key ) 根據指定的鍵刪除鍵值對。
D:獲取功能
Set<Map.Entry<K,V>> entrySet() 鍵值對對象的集合(注:entry登記,記錄)
Object get( Object key ):根據鍵獲取值。
Set<K> keySet():全部鍵的集合
Collection<V> values() 全部值的集合。
E:長度功能
int size()
(5)Map 的兩種遍歷方式
A:丈夫找妻子:根據鍵來找值
a:把全部丈夫給集合起來:Set<K> keySet()
b:遍歷丈夫集合:獲取到每個丈夫:加強for 或迭代器
c:讓丈夫去找妻子:get(Object key)
// 建立集合對象
Map<String, String> map = new HashMap<String, String>();
// 往集合裏邊添加元素
map.put("郭靖", "黃蓉");
map.put("楊過", "小龍女");
map.put("牛郎", "織女");
// 獲得全部的丈夫對象
Set<String> husbandSet = map.keySet();
// 用迭代器的方式來作
Iterator it = husbandSet.iterator();
while(it.hasNext())
{
String husband = (String)it.next();
String wife = map.get(husband);
System.out.println(husband +"-----"+ wife);
}
// 用加強for 來作
for (String s : husbandSet) {
// 根據「丈夫」找到「妻子」--根據鍵獲取值
String wife = map.get(s);
System.out.println(s + "******" + wife);
}
B:根據結婚證找丈夫和妻子:根據鍵值對來找鍵和值
a:獲取全部結婚證的集合,Set<> entrySet()
b:遍歷結婚證集合,獲取到每個結婚證對象:迭代器或加強for
c:經過結婚證對象獲取丈夫和妻子getKey()和getValue()
// 建立集合對象
Map<String, String> map = new HashMap<String, String>();
// 往集合裏邊添加元素
map.put("郭靖", "黃蓉");
map.put("楊過", "小龍女");
map.put("牛郎", "侄女");
// 找到全部的「結婚證」即全部的鍵值對封裝到一個集合中備用
Set<Map.Entry<String, String>> set = map.entrySet();
// 方式2 遍歷,這樣每次遍歷我都會獲得一個鍵值對
for (Map.Entry<String, String>  en : set) {
// 獲得鍵和值,而後打印
String key = en.getKey();
String value = en.getValue();
System.out.println(key + "****" + value);
}
2:HashMap
(1)HashMap 存儲字符串並遍歷
鍵:String
值:String
(2)HashMap 存儲自定義對象並遍歷
鍵:String
值:Student
(3)HashMap 存儲自定義對象並遍歷
鍵:Student(重寫hashCode 和equals 方法,自動生成)
值:String
需求:若是對象的成員變量值都相同則認爲是同一個對象。
3:TreeMap
(1)TreeMap 存儲字符串並遍歷
鍵:String
值:String
(2)TreeMap 存儲自定義對象並遍歷
鍵:String
值:Student
(3)TreeMap(傳入一個比較器comparator)存儲自定義對象並遍歷
鍵:Student
值:String
需求:若是對象的成員變量值都相同則認爲是同一個對象,同時還要按照年齡排序。
4:案例(理解)
(1)統計字符串中每一個字符出現的次數。
//建立集合對象
TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
String str = "cbxzbvavdvgd";
//將字符串轉成字符數組
char[] chs = str.toCharArray();
//遍歷字符數組
for (char ch : chs) {
//將拿到的字符去集合中找對應的值,根據返回值進行相應的操做
Integer i = tm.get(ch);
if (i == null) {
tm.put(ch, 1);
} else {
i++;
tm.put(ch, i);
}
}
//將獲得的鍵值對集合,根據轉變成字符串並將結果按照要求的格式打印出來
//建立可變字符串對象
StringBuilder sb = new StringBuilder();
//獲得集合中全部的鍵並遍歷
Set<Character> set = tm.keySet();
for(char ch:set)
{
//根據鍵找到對應的值, 而後按照要求的格式拼接
Integer i = tm.get(ch);
sb.append(ch).append("(").append(i).append(")");
}
//將結果轉成字符串, 並輸出
String result = sb.toString();
System.out.println(result);
(2)HashMap 嵌套HashMap 的使用。
//建立集合對象--czbk
HashMap<String,HashMap<String,String>> czbk = new
HashMap<String,HashMap<String,String>>();
//建立並添加元素對象yr 和jy
HashMap<String,String> yr = new HashMap<String,String>();
yr.put("01", "zhangsan");
yr.put("02", "lisi");
czbk.put("yr",yr );
HashMap<String,String> jy = new HashMap<String,String>();
jy.put("01", "wangwu");
jy.put("02","zhaoliu");
czbk.put("jy", jy);
//遍歷集合
//建立集合對象--czbk
HashMap<String,HashMap<String,String>> czbk = new
HashMap<String,HashMap<String,String>>();
//建立並添加元素對象yr 和jy
HashMap<String,String> yr = new HashMap<String,String>();
yr.put("01", "zhangsan");
yr.put("02", "lisi");
czbk.put("yr",yr );
HashMap<String,String> jy = new HashMap<String,String>();
jy.put("01", "wangwu");
jy.put("02","zhaoliu");
czbk.put("jy", jy);
//遍歷集合
//先拿到czbk 集合中全部的鍵, 並遍歷
Set<String> czbkKeys = czbk.keySet();
for(String czbkKey :czbkKeys)
{
//打印czbk 集合中的鍵
System.out.println(czbkKey);
//在czbk 集合中, 根據鍵拿到對應的值, 由於值也是一個鍵值對集合, 因此我
們在遍歷一次
HashMap<String,String> hm=czbk.get(czbkKey);
//拿到(czbk 的值集合)中的全部的鍵
Set<String> set = hm.keySet();
//遍歷, 根據鍵找到對應的值, 並將結果輸出
for(String s :set)
{
String value = hm.get(s);
System.out.println("\t"+s+"***"+value);
}
}
(3)HashMap 嵌套ArrayList 的使用。

part19 異常

異常
1:異常的概述
寫完代碼,代碼下面有紅線就是異常;運行程序控制臺顯示報錯了,就是異常
2:異常的體系
Throwable
Error:嚴重的問題,一般出現的是重大的問題
好比運行的類不存在或者內存溢出等,不須要處理,可是確定是要修改代碼的(找到哪一個地方有嚴重錯誤),
不然整個程序都運行不起來
Exception:不嚴重
編譯期異常:強制要求咱們處理
運行期異常:能夠不處理,也能夠處理
若是不處理:程序能夠運行起來,可是運行到報錯處
咱們在編程的過程當中確定會有不少問題的存在
爲了方便表示問題緣由、類型、位置。java 就提供了異常對象供咱們使用
異常:
程序出現的不正常狀況
對應的異常
Throwable 類
---Error(錯誤)嚴重的
一般出現重大問題:運行的類不存在或者內存溢出,不需處理,而是須要修改代碼
---Exception(異常)不嚴重的
---編譯期間的,這個須要處理
---運行期間的,這個不須要處理的,須要修改代碼或者傳遞參數
若是出現問題,咱們本身沒有處理,jvm 會才用的處理方式
他就是異常的類型緣由、位置直接顯示在控制檯,後面的代碼是不能執行的
A,編寫處理代碼:
基本格式
try{
    可能發生問題的代碼
}catch(異常類名,變量名){
異常處理代碼
}
B,拋出
代碼中有多個異常該怎麼處理,一個個的用異常處理方案解決
針對全部問題寫一個try catch,一個try 多個catch
注意:
在異常處理中,一旦try 裏出問題了直接跳到catch 裏處理
注意一個問題,異常或者錯誤都是以他們所在的體系父親做爲後綴
catch 順序:
若是異常是平級關係沒有順序;若是有子父關係,父類要放在最後
**jdk7 新特性,多個catch 用一個處理
格式:catch(異常1 | 異常2 |、、、變量名){}

part20 遞歸

遞歸定義:方法定義調用方法自己的現象。
public void show(){
show();
}
注意事項:
A:遞歸必定要有出口,不然就會死遞歸。
B:遞歸的次數不要過多,不然內存溢出。
舉例:
public void show(int n)
{
if(n==0)//出口條件,結束遞歸的條件
{
System.exit(0);
}
else{
System.out.println("hell");
show(n-1);
}
}
作遞歸的題思路
1)找遞歸出口
2)找遞歸規律
舉例:用遞歸求5!
出口:1!=1
規律:n!=n*(n-1)!
public static int jc(int n) {
if (n == 1) {
// 出口
return 1;
} else {
// 規律
return n * jc(n - 1);
}
}
案例:用遞歸求斐波那契數列
public static int fun(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return fun(n - 1) + fun(n - 2);
}
}
用遞歸求下列數列的第二十項的值: 1, 1, 2, 4, 7, 13, 24...
private static int sum(int i) {
if(i ==1){
return 1;
}else if(i==2){
return 1;
}else if(i==3){
return 2;
}else{
return sum(i-3) +sum(i-2)+ sum(i-1);
}
}
應用: 1:在控制檯輸出D:\jkdong\20160430 全部的java 文件的絕對路徑。
private static void showFiles(File file) {
// 獲取該目錄下的全部文件或者文件夾的File[]數組。
File[] fileArray = file.listFiles();
//有時候一些有權限的文件不能獲取, 因此fileArray 有可能爲null 因此要
加入判斷
if(fileArray!=null){
// 遍歷File[]數組, 獲取到每個File 對象
for (File f : fileArray) {
// 判斷該File 對數是不是目錄
if (f.isDirectory()) {
showFiles(f);
} else {
// 文件
if (f.getName().endsWith(".java")) {
System.out.println(f.getAbsolutePath());
}
}
}
}
}
2:刪除指定的目錄(目錄是帶有目錄或者文件的)
private static void deleteFiles(File file) {
//第1 步封裝文件夾
File[] fileArray = file.listFiles();//1,test_deleteFiles; 2.1,aaa_deleteFiles;
2.2,bbb_deleteFiles;
if (fileArray != null) {
//若是封裝的文件夾不爲空,那麼就進行遍歷,得到每個文件或文件夾
for (File f : fileArray) {
if (f.isDirectory()) {
//若是被封裝文件夾的子文件仍是個文件夾,那麼繼續封裝起來
進行判斷
deleteFiles(f);
} else {
//若是被封裝起來的子文件夾正好就是個文件,那麼直接刪除
System.out.println(f.getName() + "***" + f.delete());
}
}
}
System.out.println(file.getName() + "***" + file.delete());
// 若是文件夾爲空,直接刪除. 當if 語句執行完時,就表示每次封裝的目錄下
的文件被刪除完畢。
}

part21 IO 流

IO 流總結:
基本字符輸出流:FileWriter

A:建立字符輸出流FileWriter 對象(並傳入一個寫入的位置)
FileWriter fw = new FileWriter("a.txt");//必須初始化
B:調用寫數據的功能
fw.write("hello,io你好");
C:刷新緩衝區
fw.flush();
D:釋放資源(jvm 不會自動回收流的資源, 除非你手動標記該流已成爲垃圾)
fw.close();

基本字符輸入流:FileReader
//建立字符輸入流對象(而且明確你要從哪一個文件讀數據)

FileReader fr = new FileReader("FileWriterDemo.java");
//方式1:一次讀取一個字符
int ch = 0;
while((ch=fr.read())!=-1){//若是數據沒有讀取時將返回-1
//若是有數據則返回int 類型(字符的int 值),並自動移動到下一個數據位置等待讀取
S ystem.out.print((char) ch);
}

//方式2:一次讀取一個字符數組

char[] chs = new char[1024];
int len = 0;
while ((len = fr.read(chs)) != -1) {//len 表示read(chs)讀取到多少個字符
//若是實際讀取長度是-1 的狀況,那麼說明已經讀取到結尾了
System.out.print(new String(chs, 0, len));//new String(chs, 0, len)
//是爲了寫入實際讀入的數據, 不然讀取到最後的時候可能會有誤差
}
//釋放資源
fr.close();
高效字符輸出流:BufferedWriter

//建立高效字符輸出流對象
BufferedWriter bw = new BufferedWriter(new FileWriter("c.txt"));
// 寫入數據
bw.write("hello");
bw.flush();
// 釋放資源
bw.close();

高效字符輸入流:BufferedReader

BufferedReader br = new BufferedReader(new FileReader("c.txt"));
// 方式一:一次讀取一個字符
int ch = 0;
while ((ch = br.read()) != -1) {
System.out.print((char) ch);
}
// 方式二:一次讀取一個字符數組
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
System.out.print(new String(chs, 0, len));
}

//方式3:一次讀取一行

String line = null;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
// 釋放資源
br.close();

基本字節輸出流:FileOutputStream

A:建立字節輸出流對象
FileOutputStream fos = new FileOutputStream("a.txt");
B:調用寫數據的方法
fos.write(97);
C:釋放資源
fos.close();

注意:寫數據的方法有
   write(byte b)
   write(byte[] bys);
   write(byte[] bys, int start,int lenth);
   追加寫入用兩個參數構造
   FileOutputStream fos = new FileOutputStream("a.txt",true);

基本字節輸入流:FileInputStream

FileInputStream fis = new FileInputStream("b.txt");
//方式1:一次讀一個字節
int by = 0;
while ((by = fis.read()) != -1) {
System.out.println(by);
}
//方式2:一次讀一個字節數組
byte[] bys = new byte[1024];
int len = 0;
while ((len = fis.read(bys)) != -1) {
System.out.print(new String(bys, 0, len));
}
//釋放資源
fis.close();
高效字節輸出流:BufferedOutputStream

BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("4.mp4"));
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:\\11.java"));
byte[] bys = new byte[1024];
int len = 0;
while((len=bis.read(bys))!=-1){
bos.write(bys,0,len);
}
bos.close();
bis.close();

高效字節輸入流:BufferedInputStream

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
"d:\\copy.java"));
byte[] bys = new byte[1024];
int len = 0;
while((len=bis.read(bys))!=-1){
System.out.print(new String(bys, 0, len));
}
bis.close();
注意:對於文本能夠用字符流也可用字節流,對於二進制數據(圖片,音頻,視頻等)只能使用字節流

 

題目實例:

1: 複製MP3 加入異常處理的標準代碼
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("d:\\Copy.java"));
bos = new BufferedOutputStream(new FileOutputStream("copy1.java"));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2: 鍵盤錄入數據寫入文本文件
// 封裝數據源
Scanner sc = new Scanner(System.in);
// 封裝目的地
BufferedWriter bw = new BufferedWriter(new FileWriter("sc.txt"));
String line = null;
while((line=sc.nextLine())!=null){//"null"
if("over".equals(line)){
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
sc.close();
3: 在ArrayList 裏面存儲了3 個字符串元素, 請把這三個元素寫入文本文件。並在每一個元素
後面加入換行
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
BufferedWriter bw = new BufferedWriter(new FileWriter("array.txt"));
//遍歷集合
for(String str : array){
bw.write(str);
bw.newLine();
bw.flush();
}
bw.close();
4:從集合讀取數據寫入到文件
BufferedReader br = new BufferedReader(new FileReader("bw.txt"));
ArrayList<String> array = new ArrayList<String>();
String line = null;
while ((line = br.readLine()) != null) {
array.add(line);
}
br.close();
// 遍歷集合
for (String s : array) {
System.out.println(s);
}
5: 編寫複製文件的工具類
/**
**
@author itcast 工具類, 專門用於複製文本文件, 圖片等
*/
public class Copys {
private Copys() {
}//工具類的構造方法通常私有, 不容許new
/**
* 複製文本文件
**
@param src
* 數據源
* @param dest
* 目的地
*/
public static void copyFile(String src, String dest) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(src));
BufferedWriter bw = new BufferedWriter(new FileWriter(dest));
char[] chs = new char[1024];
int len = 0;
while ((len = br.read(chs)) != -1) {
bw.write(chs, 0, len);
bw.flush();
}
bw.close();
br.close();
}
/**
* 複製二進制流數據
**@param src
* 數據源
* @param dest
* 目的地
*/
public static void copyBinaryData(String src, String dest)
throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
src));
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(dest));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
6:綜合題:將d:\java 目錄下的全部.java 文件複製到d:\jad 目錄下, 並將原來文件的擴展名從.java 改成.jad
方法一:先更名再複製
// 封裝d:\\java 這個目錄
File srcFile = new File("d:\\hellodong");
// 獲取該目錄全部知足條件的File[]數組。
File[] fileArray = srcFile.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
System.out.println(dir+"---"+name);
return new File(dir, name).isFile() && name.endsWith(".java");
}
});
//判斷是否存在目的地目錄, 若是沒有, 就建立。
File destFile = new File("d:\\jad");
if(!destFile.exists()){
destFile.mkdirs();
}
// 遍歷File[]數組, 獲取到每個File 。
for (File file : fileArray) {
// file -- d:\\java\\Constant.java -- 數據源
//最終的結果: d:\\jad\\Constant.jad -- 目的地
//複製前更名
String name = file.getName(); //Constant.java
String newName = name.replace(".java", ".jad");//Constant.jad
File newFile = new File(destFile,newName);//d:\\jad\\Constant.jad
//複製文件
BufferedReader br = new BufferedReader(new FileReader(file));
BufferedWriter bw = new BufferedWriter(new FileWriter(newFile));
String line = null;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
方法二: 先複製後更名
// 封裝d:\\java 這個目錄
File srcFile = new File("d:\\java");
// 獲取該目錄全部知足條件的File[]數組。
File[] fileArray = srcFile.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir, name).isFile() && name.endsWith(".java");
}
});
// 判斷是否存在目的地目錄, 若是沒有, 就建立。
File destFile = new File("d:\\jad");//"d:\\jad\\ChangeNameDemo.java"
if (!destFile.exists()) {
destFile.mkdir();
}
// 遍歷File[]數組, 獲取到每個File 。
for (File file : fileArray) {
//file -- d:\\java\\Constant.java
String name = file.getName();//Constant.java--》d:\\java\\Constant.java
File newFile = new File(destFile, name); //d:\\jad\\Constant.java
BufferedReader br = new BufferedReader(new FileReader(file));
BufferedWriter bw = new BufferedWriter(new FileWriter(newFile));
String line = null;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
//複製完畢後更名
File[] destFileArray = destFile.listFiles();
for(File file : destFileArray){
//file -- d:\\jad\\Hello.java
//結果-- d:\\jad\\Hello.jad
String name = file.getName(); //Hello.java
String newName = name.replace(".java", ".jad");//Hello.jad
File newFile = new File(destFile,newName);//d:\\jad\\Hello.jad
file.renameTo(newFile);
}

part22 其它流、編碼表、properties

轉換流
1:標準的輸入輸出流
public static final InputStream in
System.in -- InputStream (字節輸出流) 底層是BufferedInputStream
public static final PrintStream out
System.out -- PrintStream (字節輸入流)
注意: 必須經過標準輸入流才能從控制檯錄入數據
必須經過標準輸出流才能把數據寫入控制檯顯示
2.字節輸入流轉成字符輸入流
方法:
字節流通向字符流的橋樑
InputStream --> InputStreamReader --> BufferedReader
3:字節輸出流轉字符輸出流
方法:
OutputStream -- > OutputStreamWriter --> BufferedWriter
4:編碼問題
流的編碼問題:字符流=字節流+編碼表
若是你想在IO 流中使用指定編碼下數據,用轉換流。
編碼問題其實很簡單,永遠使用同一種編碼便可。
FileReader=FileInputStream+GBK
FileWriter=FileOutputStream+GBK
//寫入的時候用的字符流的UTF-8 編碼
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("osw.txt"), "UTF-8");

// 指定編碼UTF-8
osw.write("中國");
osw.close();
//那麼讀出的時候若是用字符流也應該用UTF-8 編碼
InputStreamReader isr = new InputStreamReader(new FileInputStream(
"osw.txt"), "UTF-8");
char[] chs = new char[1024];
int len = isr.read(chs);
String str = new String(chs, 0, len);
System.out.println(str);
打印流
PrintStream:字節打印流
PrintWriter:字符打印流
打印流特色:
A:能夠寫入任意類型的數據。
B:能夠自動刷新。必須先啓動而且是使用println,printf 及format 方法纔有效。
C:能夠直接對文件進行寫入。
哪些流對象是能夠直接對文件進行操做的?
看構造方法, 是否有同時接受File 和String 類型的參數構造。
注意: 打印流只有寫數據的,沒有讀取數據的。
案例: 用打印流複製文本文件
// 封裝數據源
BufferedReader br = new BufferedReader(new FileReader(
"PrintWriterDemo.java"));
// 封裝目的地
PrintWriter pw = new PrintWriter(new FileWriter("Copy.java"), true);
String line = null;
while((line=br.readLine())!=null){
pw.println(line);
}
pw.close();
br.close();
注意:
A:讀取文件的時候,若是是文件夾,會出現:FileNotFoundException: test (拒絕訪問。)
B:寫文件的時候,若是沒有後綴名,它也會自動生成一個文件 而這個種類型的文件經過記事本類型的軟件是能夠打開的。
序列化流
序列化:把對象按照流同樣的方式傳輸或者存儲。
ObjectOutputStream 將Java 對象的基本數據類型和圖形寫入OutputStream 。
void writeObject(Object obj)
反序列化:把網絡中的流數據或者文件中的流數據還原成對象。
ObjectInputStream:ObjectInputStream 對之前使用ObjectOutputStream 寫入的基本數據和對象進行反序列化
Object readObject()
注意問題:
A:若是類的對象想被序列化流操做,請實現序列化接口。
B:看到了類實現了Serializable 接口,若是想解決黃色警告線請點擊鼠標。
java.io.NotSerializableException 沒有實現序列化接口異常
類經過實現java.io.Serializable 接口以啓用其序列化功能。
該接口被稱爲序列化接口,是一個標記接口。沒有任何功能須要實現。
類一旦實現了該接口,那麼該類的對象就能夠被序列化流進行操做。
Properties
Properties:是一個表示屬性集的集合。能夠從流中加載數據或者把數據保存到流中。鍵和值都是字符串。是惟一一個能夠和IO 流結合使用的集合類。
Properties 的父親是Hashtable,因此知道它是一個Map 體現的。那麼就存儲數據並遍歷。
Properties 做爲集合的特殊功能:
1: 修改功能
public Object setProperty(String key,String value)
2: 獲取功能
public String getProperty(String key)
public String getProperty(String key,String defaultValue)
public Set<String> stringPropertyNames()
System 類的一個方法: public static Properties getProperties():系統屬性
Properties 做爲和IO 流結合使用的集合的特殊功能:
public void list(PrintStream out): 把集合中的數據按照鍵值對的形式存儲到文本文
件中。
public void list(PrintWriter out): 把集合中的數據按照鍵值對的形式存儲到文本文件
中。
public void load(InputStream inStream): 從文本文件中把數據加載到集合中。
public void load(Reader reader): 從文本文件中把數據加載到集合中。
注意: 對文本文件是有要求的, 要求數據必須是鍵值對形式。
public void store(OutputStream out,String comments): 把集合中的數據保存到文本
文件中。
public void store(Writer writer,String comments): 把集合中的數據保存到文本文件
中。
注意:store 和list 方法的區別list 的參數值能是PrintWriter 或PrintStream
而store 的參數是PrintStream 或者Writer
綜合案例: 我有一個學生類,這個類包含一下成員變量:姓名,語文成績,數學成績,英語成績。
請從鍵盤錄入5 個學生信息,而後按照本身定義的格式存儲到文本文件中;要求被存儲的學生按照分數從高到低排序。
// 寫一個學生類,有4 個成員變量。
System.out.println("學生信息錄入開始");
// 須要用到排序,定義TreeSet 集合
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 主要條件
int num = s2.getSum() - s1.getSum();
// 分析次要條件
// 當總分相同,還得繼續比較每一門的分數是否相同
int num2 = (num == 0) ? s1.getChinese() - s2.getChinese() : num;
int num3 = (num2 == 0) ? s1.getMath() - s2.getMath() : num2;
// 當語文,數學,英語成績都相同的還得繼續判斷姓名是否相同。
int num4 = (num3 == 0) ? s1.getName().compareTo(s2.getName())
: num3;
return num4;
}
});
for (int x = 0; x < 5; x++) {
// 用Scanner 實現鍵盤錄入。
Scanner sc = new Scanner(System.in);
// 鍵盤錄入數據
System.out.println("請輸入第" + (x + 1) + "個學生的姓名:");
String name = sc.nextLine();
System.out.println("請輸入第" + (x + 1) + "個學生的語文成績:");
int chinese = sc.nextInt();
System.out.println("請輸入第" + (x + 1) + "個學生的數學成績:");
int math = sc.nextInt();
System.out.println("請輸入第" + (x + 1) + "個學生的英語成績:");
int english = sc.nextInt();
// 把數據封裝到學生對象中
Student s = new Student();
s.setName(name);
s.setChinese(chinese);
s.setMath(math);
s.setEnglish(english);
ts.add(s);
}
// 遍歷集合,獲取到集合中的每個數據,用輸出流寫到文本文件。
BufferedWriter bw = new BufferedWriter(new FileWriter("students.txt"));
bw.write("姓名\t 語文\t 數學\t 英語");
bw.newLine();
bw.flush();
for (Student s : ts) {
StringBuilder sb = new StringBuilder();
sb.append(s.getName()).append("\t").append(s.getChinese()).append("\t").append(s.getMath()).append("\t").append(s.getEnglish());
bw.write(sb.toString());
bw.newLine();
bw.flush();
}
bw.close();
System.out.println("學生信息錄入成功");

part23 多線程

多線程:應用程序有多條執行路徑。
進程:正在運行的應用程序。
線程:一條路徑,進行的執行單元。
注意:線程是依賴於進程,而進程是操做系統直接建立的。
Java 語言是不能直接調用操做系統的屬性的。C 語言能夠。
爲何要使用多線程?何時使用?爲了提升效率。
當要操做的代碼比較多(耗時),循環次數比較多的時候就可使用多線程。
多線程怎麼實現呢?
方式1:繼承Thread 類
A: 建立一個類(MyThread),繼承Thread 類。
B: 重寫Thread 類中的run()方法。
C: 啓動並執行線程。
注意:這裏是不能直接調用run()方法,須要調用start()方法。start()方法作了兩件事:
A:啓動線程。
B:自動調用run()方法。
同一個線程對象start()兩次,會報一個異常:IllegalThreadStateException(線程狀態異常。)
Thread 類的兩個方法:
public final String getName(); 獲取線程名稱(Thread-編號, 編號是從0 開始)
public final void setName(String name); 設置線程名稱。
public static void sleep(long mills); 讓當天線程睡一段時間(根據傳過來的毫秒值)
線程執行的隨機性的原理:因爲CPU 在作着高效的切換。程序的執行,其實就是在搶CPU 資源。
方式2:實現Runnable 接口。
A: 建立一個類(MyRunnable)實現Runnable 接口。
B: 重寫run()方法。
C: 建立類(MyRunnable)的實例。
D: 把類(MyRunnable)的實例,作爲Thread 類的構造參數傳遞。
注意事項:
由於MyRunnable 這個類是實現了Runnable 接口,因此在類中不能直接使用Thread 類的getName()這個方法。
怎麼用呢?
public static Thread currentThread(); 返回正在執行的線程的引用(Thread.currentThread().getName())
既然有了第一種實現方式,爲何要有第二種實現方式?
A:避免了單繼承的侷限性。
B:實現Runnable 接口的方式,只建立了一個資源對象,更好的實現了數據(my)和操做(start())的分離。
開發中經常使用:實現Runnable 接口的方式。
多線程的生命週期圖:
A: 新建(建立一個線程對象)
B: 就緒(具有執行資格, 不具有執行權)
C: 有可能發生阻塞(不具有執行資格和執行權)
sleep(),wait()
notify()
D: 運行(具有執行資格和執行權)
E: 死亡(線程對象變爲垃圾, 等待垃圾回收器回收。)
多線程模擬買票出現了負數和重複值? 產生緣由是什麼? 怎麼解決呢?
產生負數:
public class TicketRunnable implements Runnable {
public int tickets = 200;
@Override
public void run() {
while (true) {
//t1,t2,t3,t4 都進來了
//最後一次tickets 的值是1
if (tickets > 0) {
/*
* t1 知足, 進來了,
* t2 進來了,
* t3,
* t4 都進來了
* */
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*
* t1 醒了, 搶到了資源, 打印: 第一張票,完了之後, tickets 的值變成了0
* t2 醒了, 搶到了資源, 打印: 第0 張票, 完了之後, tickets 的值變成了-
1
* t3 醒了, 搶到了資源, 打印: 第-1 張票, 完了之後, tickets 的值變成了-
2
* t4 醒了, 搶到了資源, 打印: 第-2 張票, 完了之後, tickets 的值變成了-
3
* */
System.out.println(Thread.currentThread().getName() + "正在出售第"
+ (tickets--) + "張票");
}
}
}
}
產生重複值:
關鍵點:ticket--(ticket = ticket - 1)
A:獲取ticket 的值。
B:修改ticke 的值。
C:把修改後的值,從新賦值給ticket 。
當步驟A 執行完後,還沒來得及執行B,這個時候別的線程搶到了資源,打印的就是重複值。
產生緣由:
因爲線程的隨機性和延遲性,致使線程訪問共享數據出現了問題。
解決方案:找到可能出問題的代碼,而後把可能出問題的代碼用鎖鎖起來。
A:如何找可能出問題的代碼?
一、是否有共享數據。
二、是否有多條語句操做共享數據。
三、是否在多線程環境中。
這三點也是多線程產生問題的緣由。
B:怎麼鎖?
能夠採用同步代碼塊的方式鎖。
synchronized (鎖對象)
{
要被鎖的代碼。
}
注意:
一、鎖對象能夠是任意對象。
二、多個線程的鎖對象必須是同一個。不然可能會出現鎖不住的狀況。
鎖的狀態:開,關。
不同同步機制的鎖對象分別是什麼?
同步代碼塊:能夠是任意類型。
同步方法:把synchronized 定義在方法的聲明上。(寫在方法的返回值的數據類型以前)
public synchronized void show();
this 。
靜態方式:
當前類的字節碼文件對象。
類名.class
之後使用同步代碼塊仍是同步方法?
看需求,可是同步的代碼越少越好,因此通常使用同步代碼塊。
若是一個方法中全部的代碼都被加鎖了,那麼能夠考慮使用同步方法。
線程間的通訊問題:
線程通訊:不同種類的線程間對共享數據的操做問題。
用學生類的案例來演示線程通訊;
學生類: Student (資源類)
設置值: SetStudent (一個共享數據, 實現了Runnable 接口)
獲取值: GetStudent(一個共享數據, 實現了Runnable 接口)
測試類:
正常的邏輯:
針對輸出:( GetStudent)
判斷是否有數據, 若是有就輸出數據, 沒有的話, 就等待設置。
(喝水: 判斷水杯是否有水, 若是有就喝, 若是沒有, 就等待小蜜去接水)
針對設置; (SetStudent)
判斷是否有數據, 若是有就等待輸出, 若是沒有, 就設置。
(接水: 判斷水杯是否有水, 若是有等待喝, 若是沒有, 就接水。)
定義了一個標記: true 表明有數據, false 表明沒有數據。
面試題: wait()方法和sleep()這個方法有什麼區別?
wait(): Object 類下的方法, 不須要傳遞參數。釋放鎖對象, 釋放資源。
sleep(): Thread 類, 須要傳遞參數, 不釋放鎖對象。
等待喚醒機制的原理:
Object 類中的兩個方法:
wait(): 讓當前線程處於等待狀態。
notify(): 喚醒等待的線程。
線程的優先級;
public final void setPriority(int newPriority); 設置線程的優先級
public final int getPriority(); 獲取線程的優先級
線程默認的優先級是5, 範圍是1-10.
注意:
線程的優先級越高, 並不表明該線程必定第一個執行。
線程優先級能夠再必定程度上, 讓該線程獲取較多的執行機會。
線程的拓展:
暫停線程:
public static void yield(); 暫停當前正在執行的線程對象, 並執行其餘線程。
何時用?
他可讓線程更和諧一點的運行, 避免出現成片數據的狀況。
注意: 若是想要真正的實現數據依次輸出, 還得使用等待喚醒機制。
加入線程:
public final void join(); 等待該線程終止。
何時用?
當某個線程(A)須要在某個線程(B)執行結束後才執行, 就可使用「加入線
程」 。
例子: 當線程B 執行完後才能執行線程A,
守護線程:
public final void setDaemon(boolean on); 設置線程爲守護線程, 一旦前臺線程(主
線程)結束了, 守護線程緊跟着就結束了。
main 方法也是一個線程。

part24 網絡編程

網絡編程概述
計算機網絡:
概念:地理位置不同的多臺計算機, 網絡線路鏈接。網絡管理軟件, 網絡協議,實現資源共享和信息傳遞
分類: 局域網,城域網,廣域網,萬維網
網絡編程:用來實現網絡互聯的不同計算機運行的程序間數據交換
網絡模型:網絡之間使用何種規則進行通訊
osi 七層參考模型
物理層,定義物理設備,傳輸比特流
數據鏈路層,mac 地址的封裝與解封裝(交換機)
網絡層,ip 地址的封裝與解封裝(路由器), 數據包
傳輸層,定義傳輸協議和端口號(tcp udp)
會話層,發起會話或者接受會話請求
表示層,解釋加密解密壓縮解壓縮(完成翻譯)
應用層,終端應用,直接使用的軟件,面向用戶
tcp/ip 模型
主機到網絡層--物理層, 鏈路層
網際層--網絡層
傳輸層--傳輸層
應用層--會話層, 表示層, 應用層
網絡通訊三要素
網絡通訊(Socket 通訊, 套接字編程)
實現網絡互連的不同計算機上運行的程序間能夠進行信息交換
即用java 語言實現不同計算機間的通訊
三要素:
IP 地址:Ip 是網絡中每一臺計算機的惟一標識
端口:用於標識進程的邏輯地址,不同的進程(應用程序)擁有不同的端口
協議:定義通訊規則--udp 和tcp 協議
IP 地址
概念:網絡中的計算機的惟一標識
表示形式:點分十進制計數法--192.168.0.100
二進制對應的十進制
二進制太長不方便記憶
每段(8 位)範圍0~255
ip 地址分類
A 類1.0.0.1-127.255.255.254(10.x.x.x 是私有地址)
B 類128.0.0.1--191.255.255.254(172.16.0.0--172.31.255.255 爲私有)
C 類192.0.0.1--223.255.255.254
D 類224.0.0.1--223.255.255.254
E 類240.0.0.1--247.55.255.254
ip 地址組成
網絡號碼+主機地址
A 類第1 段爲網絡號碼, 後3 個是本地主機的地址: 256^3 個主機(廣域網)
B 類前2 段爲網絡號碼, 後2 個是本地主機的地址: 256^2 個主機(校園網)
C 類前3 段爲網絡號碼, 後1 個是本地主機的地址: 256 個主機(局域網)
查看本機ip: win+r-->cmd-->ipconfig /all
查看網絡是否有問題: ping+ip 地址
ping:127.0.0.1 本機迴環地址: 檢查本機環境是否有問題
ping:x.x.x.x 別人地址檢查外部環境是否有問題
ping:x.x.x.x -t 向。。一直髮包
端口號:
每一個網絡進程至少有一個邏輯端口
用於標識進程的邏輯地址, 不同進程標識不同樣
有效端口: 0~65535(255^2).其中0~1024 是系統使用或者保留端口
**協議: 定義的通訊規則
udp 協議
數據打包(將數據源和目的地封裝成數據包)
數據有限制(數據包限制在64k)
面向無鏈接(不須要創建鏈接)
不可靠協議
速度快
舉例: QQ 羣聊, 短信
tcp 協議: 三次握手協議--請求, 迴應, 發送
創建鏈接通道
數據沒有限制
面向鏈接的協議(三次握手)
可靠
速度慢
舉例: 藍牙, QQ 單聊, 打電話
用什麼: 看需求
Socket 編程
是爲網絡編程提供一種機制, 包裝了端口和ip 地址
特色:
數據兩端都獨有Socket
網絡通訊實際就是Socket 通訊
數據在兩個Socket 間經過IO 傳輸
Socket 通訊--套接字編程--網絡編程
InetAddress 類
ip 地址的包裝類, 該類的構造方法是私有的,
怎麼該類的對象:
InetAddress getByName(String host),根據主機名返回對應的ip 地址(對象
形式)
注意: 參數能夠是主機名也能夠是ip 地址
成員方法:
getHostAddress();返回ip 地址(字符串)
getHostName();返回主機名
udp 發送步驟
建立發送端Socket 發送對象
DatagramSocket 類的無參構造
建立數據並把數據打包
DatagramPacket(byte[] bys,length,InetAddress ip,port(端口號))
發送數據
send(DatagramPacket dp)
釋放資源
ds.close();
udp 接收步驟
建立接受端Socket 對象
DatagramSocket(int port)
建立數據包(接收容器)
DatagramPack(byte[] bys,int length)
調用接收方法
receive(dp)
*解析數據包, 把數據顯示在控制檯, 從包裏拿到須要的對象
從數據包中得到ip(字符串ip)
InetAddress getAddress()
InetAddress getHostAddress()
從數據包中得到客戶端發的數據
byte[] getData();
int getLength();//獲取實際長度
釋放
ds.close();
注意:
發送接收的端口必定要一致
一個端口不能夠被多個程序使用
案例: 聊天室(掌握)
Scoket 類
Tcp 協議客戶端的步驟
建立客戶端Socket 對象
Socket(host,port) host 能夠是ip 地址
創建鏈接
獲取輸出流, 寫數據便可, 往服務器發送數據
OutputStream getOutputStream();
釋放資源
tcp 協議服務器端步驟
建立服務器Socket 對象
ServerSocket(int port)
監聽鏈接
public Socket accept();監聽並接收到此套接字的鏈接
獲取輸入流, 讀取數據並顯示
public InputStream getInputStream()
釋放
注意:
必須先開服務器端, 而後再開啓客戶端, 不然程序會出錯
鍵盤錄入數據寫入文本文件
數據寫進去了, 但服務器反饋沒有成功
緣由:

part25 正則反射

正則表達式:
概述:就是符合某種規則的字符串。
需求:
判斷是不是QQ 號碼。(5-15 位數字,不能以0 開頭)
[1-9][0-9]{4,14}
規則字符: Pattern 類
A:字符
n 字符n 自己出現一次
\\ 在正則中,兩個\表示一個\
\r 回車
\n 換行
B:字符類
[abc] a,b,c 任意一個字符出現一次
[^abc] 任意字符,a,b,c 除外
[a-zA-Z] 全部的英文字母一次
[0-9]任意數字一次
C:預約義字符類
. 單獨的一個點表示任意字符一次
\d 任意數字一次, 至關於[0-9]
\w 單詞字符(字母, 數字, _),至關於[a-zA-Z_0-9]
D:邊界匹配器
^ 行的開頭
$ 行的結尾
\b 這裏出現的不能是單詞字符
E:數量詞
n? 字符n 一次或一次都沒有
n* 字符n 零次或者屢次
n+ 字符n 一次或者屢次(至少一次)
n{a} 字符n 剛好出現a 次
n{a,} 字符n 至少出現a 次
n{a,b} 字符n 至少出現a 次, 不超過b 次
基本功能:
判斷功能:
public boolean matches(String regex); 判斷該字符串是否與給定的正則表達式匹配。
切割功能:
public String[] split(String regex); 按照給定的正則切割該字符串
替換功能:
public String replaceAll(String regex, String replacement);
用指定的字符串來替換字符串中全部符合正則規則的字符串。
regex:正則,用來檢索要替換的字符串
replacement:用來替換的字符串。
獲取功能:
使用的是模式對象Patter 和匹配器Matcher 對象。
Matcher 類下的兩個方法:
public boolean find();嘗試查找與該模式匹配的輸入序列的下一個子序列。
理解:就是大串中查找小串,看是否有符合規則的小串。
public String group();
返回由之前匹配操做所匹配的輸入子序列。
理解:就是返回剛纔查找到的,符合規則的小串。
A: 經過字符輸入流來讀取文本文件。
B: 對讀到的每一行數據進行校驗。
C: 若是數據符合需求, 就把該數據存到集合中。
D: 遍歷集合。
反射:
概述:在運行期間,能夠經過Class 文件對象(字節碼文件對象)來使用構造方法,成員變量,成員方法。
怎麼獲取Class 文件對象:
A:Object 類中的getClass()方法。
B:數據類型的靜態的class 屬性(類名.class)
C:Class 類中的forName(String className); 注意;className 的名字要是帶全路徑的。
開發中經常使用第三種,由於它能夠結合配置文件使用。
注意:一個類能夠有多個對象,可是隻能有一個Class 文件對象。

part26 設計模式

概述:把類似的東西抽取出來的模型分類建立型模式:建立對象。--工廠模式,單例模式結構型模式:類與類的關係(研究對象間的關係)--裝飾模式行爲型模式:對象可以作什麼。--模版模式GOF 設計模式(23 種)人:閆閎(國內研究設計模式較早的)建立型模式:工廠模式簡單工廠模式AnimalDogCatAnimal工廠方法模式原理首先咱們先寫一個動物的抽象工廠類, ()當咱們須要一個新對象的時候, 按照以下操做寫一個該該類的實體類去繼承動物類寫一個該類的工廠類去繼承動物類而後在該類的工廠類中建立該類對象AnimalDogCatPigAnimalFactoryDogFactory extends AnimalFactoryCatFactory extends AnimalFactoryPigFactory extends AnimalFactory測試類單例模式:類在內存中只存在一個對象--如網站訪問統計、windows 打印服務應用: 線程池, 數據庫鏈接池面試題: 寫出一個單例設計模式分析: 類在內存中只存在一個對象外界不能隨意建立對象把構造方法私有類自己要建立一個對象靜態方法只能訪問靜態, 對象要加靜態爲了不讓外界經過類名直接訪問就加私有經過公共的方式提供給別人: public 修飾的方法爲了讓外界可以直接經過類名訪問該方法, 須要對方法加靜態餓漢式: (開發中用)類一加載就建立對象public Student {private Student(){}//類一加載就建立對象private stattic Student s = new Student();public static Student getStudent(){return s;}}Student s = Student.getStudent();懶漢式:(面試中用):何時用就何時建立對象jdk 中的單例模式:RunTome 類public Student {private Student(){}//何時用就何時建立對象//面試時別忘加鎖private synchronized stattic Student s = null;public static Student getStudent(){if(s==null){s = new Student();}return s;}}爲何懶漢式: (面試中用)懶漢式是延遲加載: 何時用, 何時建立對象懶漢式有線程安全問題: 方法上加鎖裝飾模式: 一種是經過繼承實現, 一種是經過實現接口實現對類原有的功能進行修飾和包裝擴展實現步驟:找到裝飾的抽象事物Phone建立一個實體類(PhoneImple)只有打電話功能, 來實現或者繼承第一步的抽象事物(Phone 接口)建立一個裝飾類(PhoneDecorate), 來實現Phone 接口, 調用實體類對象裝飾類子類繼承裝飾類, 重寫裝飾類的方法, 實現功能擴充Phone 接口PhoneImpl 具體實現類PhoneDecorate 抽象類ColorPhoneDecorate 具體裝飾類GuangGaoPhoneDecorate 具體裝飾類模板方法模式最優體現是以抽象類的形式體現的打印模板類打印方法: 具體的三個抽象方法具體實現類1具體實現類2需求: 模仿剛纔的代碼, 用模板方法模式設計一個計算, 程序運行時間的模板類long start = System.currentTimeMillis();code()long end = System.currentTimeMillis();

相關文章
相關標籤/搜索