Java面向对象基础呕心沥血三千字
# 一、初識(shí)Java
## 1.java關(guān)鍵字
public?? ?公共的、公開(kāi)的?
class?? ?類
static?? ?靜態(tài)的
void?? ?空的?? ?
main?? ?main方法
String?? ?字符串
System ?系統(tǒng)
## 2.注意點(diǎn)
1)注意大括號(hào)、小括號(hào)、中括號(hào)成對(duì)出現(xiàn)
2)注意每一行代碼后有分號(hào)結(jié)束
3)注意所有符號(hào)都是英文符號(hào)
4)注意縮進(jìn)(tab ?shift+tab)
5)公共類的類名要和源文件名同名
## 3.java注釋
### 1)單行注釋
//
### 2)多行注釋
/*
?....
*/
### 3)文檔注釋(javadoc注釋)
/**
?....
*/
## 4.常用快捷鍵
ctrl + s ?? ??? ??? ??? ?保存
ctrl + c?? ??? ??? ??? ?復(fù)制
ctrl + v?? ??? ??? ??? ?粘貼
ctrl + x?? ??? ??? ??? ?剪切
ctrl + z?? ??? ??? ??? ?撤銷上一步操作
ctrl + y?? ??? ??? ??? ?返回下一步操作
ctrl + a ?? ??? ??? ??? ?全選
ctrl + shift + 左右鍵 ?? ?選擇單詞
shit + home/end ?? ??? ?選擇一整行
alt + 上下鍵?? ??? ??? ?把光標(biāo)所在行上下移動(dòng)
alt + shift + r ?? ??? ?重命名
alt + insert?? ??? ??? ?新建
shift + 上下左右鍵 ?? ??? ?選擇內(nèi)容
ctrl + / ?? ??? ??? ??? ?注釋
ctrl + shift + f?? ??? ?格式化代碼
# 二、變量、數(shù)據(jù)類型以及運(yùn)算符
## 1.變量
變量類型:char、int、double、String
java中的8種基本類型:
byte char short int long float double boolean
變量命名規(guī)范:
可以由字母、數(shù)字、下劃線、$符號(hào)組成,開(kāi)頭不能是數(shù)字
使用駱駝命名法命名(首字母小寫(xiě),后面每個(gè)單詞首字母大寫(xiě))
起有意的名字,見(jiàn)名知意
## 2.常量
final關(guān)鍵字用來(lái)修飾常量
final int num = 10;
num=100;//這一行報(bào)錯(cuò),因?yàn)槌A坎辉试S修改
## 3.運(yùn)算符
### 1)賦值運(yùn)算符
= 運(yùn)算時(shí)把右側(cè)的值賦值給左側(cè)
### 2)算術(shù)運(yùn)算符
+ -/ %
注意:
如果操作數(shù)都是整數(shù)
/ 是用來(lái)取商的
% 是用來(lái)取余數(shù)的
如果操作數(shù)中有一個(gè)是double(也可以都是)
則 / 可以計(jì)算出小數(shù),需要用double來(lái)接收結(jié)果
### 3)比較運(yùn)算符
==、>、<、>=、<=、!=
### 4)邏輯運(yùn)算符
&& ?: 并且(與)
|| ?: 或者(或)
! ? : 非
優(yōu)先級(jí):非、與、或
/*
?* 討論關(guān)于java中幾種運(yùn)算符之間的執(zhí)行優(yōu)先級(jí)
?* 1."()"運(yùn)算優(yōu)先級(jí)最高,一般可用于手動(dòng)改變表達(dá)式中不同運(yùn)算符的運(yùn)算順序
?* 2.“!”,“++”,“--”稱為單目運(yùn)算符(只對(duì)一個(gè)操作數(shù)進(jìn)行運(yùn)算稱為單目),優(yōu)先級(jí)高
?* 3.對(duì)一些常用的運(yùn)算符(雙目)之間:算術(shù)運(yùn)算符 > 關(guān)系運(yùn)算符 > 邏輯運(yùn)算符
?* ? 3.1 算術(shù)運(yùn)算符中: + - * / % ++ --
?* ? ? ? 除++,--之外:* / % 優(yōu)先于 + - ,當(dāng)有并列優(yōu)先級(jí)時(shí)例如: 4 * 5 / 2,從左向右運(yùn)算
?* ? 3.2 關(guān)系運(yùn)算符: == ?!= ? > ? < ? >= ? <=
?* ? ? ? > ? < ? >= ? <= 只能用于數(shù)值類型的數(shù)據(jù)比較
?* ? ? ? > ? < ? >= ? <= 優(yōu)先級(jí)高于 ?== ?!=
?* ? ? ? 當(dāng)有并列優(yōu)先級(jí)時(shí)例如: 5 > 3 == 2 < 4 ,從左向右運(yùn)算
?* ?3.3 邏輯運(yùn)算符: & ?&& ?| ?|| ?!
?* ? ? ?除!外:&& 優(yōu)先于 ||
?* ? ? ?邏輯與(&) 同 短路與(&&) 相比:不論第一個(gè)操作數(shù)是否為false,都會(huì)運(yùn)算第二個(gè)操作數(shù),而短路與不會(huì)
?* ? ? ?邏輯(|) ?同 ?短路或(||) 相比: 不論第一個(gè)操作室是否為true,都會(huì)運(yùn)算第二個(gè)操作數(shù),而短路或不會(huì)
?* 4. ?“=”,"?:","!","++","--"這5個(gè)符合在運(yùn)算時(shí)從右向左。
?* 總結(jié):
?* ? ? ?"!","++","--"(同時(shí)出現(xiàn)在一個(gè)表達(dá)式中時(shí),從右向左)
?* ? ? ?優(yōu)先于
?* ? ? ?"*","/","%" (從左向右)
?* ? ? ?優(yōu)先于
?* ? ? ?"+","-" (從左向右)
?* ? ? ?優(yōu)先于
?* ? ? ?">","<",">=","<="(從左向右)
?* ? ? ?優(yōu)先于
?* ? ? ?"&","&&"
?* ? ? ?優(yōu)先于
?* ? ? ?"|","||"
?* ? ? ?優(yōu)先于
?* ? ? ?"?:"
?* ? ? ?以上優(yōu)先級(jí)為java表達(dá)式運(yùn)算時(shí)的默認(rèn)執(zhí)行順序,任何一個(gè)運(yùn)算符在使用“()”時(shí)都將提升為最高,
?* ? ? ? 有多個(gè)()并列出現(xiàn)時(shí),從左往右
?* ? ? ? 有多個(gè)()嵌套出現(xiàn)時(shí),從內(nèi)向外
?*/
## 4.類型轉(zhuǎn)換
### 1)自動(dòng)類型轉(zhuǎn)換
int a = 5;
double b = 2.5;
double c = a + b; //表達(dá)式中如果有double類型,則整體運(yùn)算結(jié)果提升為double類型
int a = 5;
double b = a; ?? ? ?//自動(dòng)提升,int可以直接賦值給double
### 2)強(qiáng)制類型轉(zhuǎn)換
double a = 123.567;
int b = a; ?? ??? ?//這樣會(huì)報(bào)錯(cuò),double類型不能直接賦值給int類型,數(shù)據(jù)寬度問(wèn)題
int b = (int)a; // 這樣就是強(qiáng)轉(zhuǎn)了,b的結(jié)果是123,小數(shù)部分舍棄
## 5.其他
### 1)從控制臺(tái)輸入
先導(dǎo)包
import java.util.Scanner;
再聲明Scanner對(duì)象
Scanner input = new Scanner(System.in)
再使用相應(yīng)的方法從控制臺(tái)獲取用戶輸入的數(shù)據(jù)
String name = input.next();
int age = input.nextInt();
double score = input.nextDouble();
### 2)++的問(wèn)題
int a = 5;
a++; ?//等價(jià)于 a = a + 1
# 三、流程控制—選擇結(jié)構(gòu)和循環(huán)結(jié)構(gòu)
## 1.流程圖
菱形:條件判斷
矩形:運(yùn)算
平行四邊形:輸入、輸出
圓角矩形:開(kāi)始、結(jié)束

## 2.if語(yǔ)句
if(條件){
? //代碼塊
}?? ?
if(條件){
? //代碼塊1
}else{
? //代碼塊2
}
多重if語(yǔ)句 :
if(條件1){
? //代碼塊1
}else if(條件2){
? //代碼塊1
}else{
? //...
}
嵌套if語(yǔ)句:
if(條件1){
? //...
? if(條件2){
? ? //...
? }
? //...
}else{
? //....
}
## 3.字符串的判斷相等
equals() 字符串等值比較
equalsIgnoreCase() 忽略字母大小寫(xiě)進(jìn)行比較
## 4.switch
注意點(diǎn):
1)switch的變量類型允許的:
? int、char、byte、short、String(jdk1.8以后)
1)case后的常量不能重復(fù)
2)case的順序可以調(diào)換
3)break如果省略,會(huì)出現(xiàn)貫穿的情況
4)default一般放在最后,其中的break可以省略
? 從語(yǔ)法上來(lái)看default也可以省略
/*
?* switch分支結(jié)構(gòu)的特點(diǎn):
?* 1、只能用于表達(dá)式運(yùn)算結(jié)果和case之后的常量值之間的等值判斷
?* 2、表達(dá)式只能是:int,short,byte,char,String,枚舉這些類型
?* 3、在每個(gè)case后的break可以省略,
?* ? 若省略則執(zhí)行該case分支代碼后將“貫穿”執(zhí)行下一個(gè)case的代碼塊,
?* ? 這種“貫穿”直到遇到break或者switch的”}“為止
?* 4、多個(gè)case后的常量值不能相同
?* 5、如果default的位置不在最后,表達(dá)式判斷的順序不變,
?* ? ?仍舊是先判斷所有case,在不滿足任何case后才執(zhí)行default分支
?* 6、當(dāng)有等值判斷的多分支需求時(shí),超過(guò)3個(gè)以上分支使用switch效率比多重if要高
?*/

# 四、數(shù)組
## 1.數(shù)組的定義
存儲(chǔ)固定大小的同類型元素
## 2.數(shù)組的創(chuàng)建
~~~java
int[] nums;//聲明數(shù)組
nums = new int[5];//創(chuàng)建數(shù)組
int[] nums1 = new int[5];//聲明并創(chuàng)建數(shù)組
int nums2 = {1,2,3,4,,5};//創(chuàng)建的同時(shí)并給數(shù)組賦初始值
int nums3 = new int{1,2,3,4,5};//創(chuàng)建的同時(shí)并給數(shù)組賦初始值
~~~
## 3.數(shù)組的訪問(wèn)
通過(guò)下標(biāo)訪問(wèn)
# 五、面向?qū)ο蠛头庋b
## 1.類和對(duì)象的關(guān)系
類是對(duì)象的抽象,對(duì)象是類的具體表現(xiàn)
## 2.類的成員:
+ 屬性:描述類的靜態(tài)特征
? + 類變量:類加載時(shí)就會(huì)分配空間,通過(guò)類名調(diào)用,不提倡通過(guò)對(duì)象調(diào)用
? + 成員變量:調(diào)用構(gòu)造函數(shù)時(shí)才會(huì)分配空間,只能通過(guò)對(duì)象調(diào)用。
+ 方法:描述類的動(dòng)態(tài)行為
+ 代碼塊:
? + 靜態(tài)代碼塊:加載類是執(zhí)行的代碼塊
? + 代碼塊:定義對(duì)象是執(zhí)行的代碼塊
## 3.構(gòu)造方法
+ 初始化類的屬性
+ 方法名與類名相同
## 4.對(duì)象的創(chuàng)建
~~~java
Car car = new Car(); //new 關(guān)鍵字創(chuàng)建空間,構(gòu)造方法用于初始化屬性
~~~
# 六、繼承和多態(tài)
## 1.繼承的基本概念
繼承是從已有的類創(chuàng)建新類的過(guò)程。
+ 繼承是面向?qū)ο蟮娜筇卣髦?br /> + 被繼承的類被稱為父類(超類),繼承父類的類叫做子類(派生類)
+ 繼承是指一個(gè)對(duì)象直接使用另一個(gè)對(duì)象的屬性和方法
+ 通過(guò)繼承可以實(shí)現(xiàn)代碼重用
## 2.繼承的限制
+ java只能實(shí)現(xiàn)單繼承,也就是一個(gè)類只能又一個(gè)父類。
+ 允許多層繼承,即:一個(gè)子類可以有一個(gè)父類,一個(gè)父類還可以有其他的父類。
+ 繼承只能繼承非私有的屬性和方法。
+ 構(gòu)造方法不能被繼承

## 3.子類的實(shí)例化過(guò)程
在子類經(jīng)行實(shí)例化操作的時(shí)候,首先會(huì)讓其父類進(jìn)行初始化操作,之后子類再自己進(jìn)行實(shí)例化操作。
### 1)子類的實(shí)例化過(guò)程:
子類實(shí)例化時(shí)會(huì)先調(diào)用父類的構(gòu)造方法,如果父類中沒(méi)有默認(rèn)的構(gòu)造方法,在子類的構(gòu)造方法中必須顯示的調(diào)用父類的構(gòu)造方法?? ?。
### 2)結(jié)論:
構(gòu)造方法只是用于初始化類中的字段以及執(zhí)行一些初始化代碼,**調(diào)用構(gòu)造方法并不代表會(huì)產(chǎn)生對(duì)象**。
## 4.方法重寫(xiě)
### 1)方法重寫(xiě):
在java中,子類可以繼承父類中的方法,而不需要重新編寫(xiě)相同的方法。但有時(shí)子類不想原封不動(dòng)地繼承父類的方法,而是想做一定的修改,這就需要采用方法的重寫(xiě)。方法重寫(xiě)又稱方法覆蓋。在子類和父類中,重寫(xiě)方法后,在調(diào)用時(shí),以創(chuàng)建的對(duì)象類型為準(zhǔn),會(huì)調(diào)用誰(shuí)的方法。
### 2)方法重寫(xiě)的一些特性
+ 發(fā)生在子父類中,方法重寫(xiě)的兩個(gè)方法的返回值、方法名、參數(shù)列表必須完全一致。
+ 子類拋出的異常不能超過(guò)父類相應(yīng)方法拋出的異常。
+ 子類方法的訪問(wèn)級(jí)別不能低于父類相應(yīng)方法的訪問(wèn)級(jí)別。
+ 父類中的方法若使用private、static、final任意修飾符修飾,不能被子類重寫(xiě)。

## 5.super關(guān)鍵字
+ 使用super調(diào)用父類中的屬性,可以從父類實(shí)例中獲得信息。
+ 使用super調(diào)用父類中的方法,可以委托父類對(duì)象幫助完成某件事情。
+ 使用super調(diào)用父類的構(gòu)造方法(super(實(shí)參)形式),必須在子類構(gòu)造方法中的第一條語(yǔ)句,調(diào)用父類中相應(yīng)的構(gòu)造方法,若不顯示的寫(xiě)出來(lái),默認(rèn)調(diào)用父類無(wú)參的構(gòu)造方法。
## 6.final關(guān)鍵字
+ 使用final關(guān)鍵字聲明一個(gè)變量:修飾屬性或者修飾局部變量,也稱為常量。
+ 使用final關(guān)鍵字聲明一個(gè)方法:該方法為最終方法,只能被子類繼承,不能被子類改寫(xiě)。
+ 使用final關(guān)鍵字聲明一個(gè)類:該類就轉(zhuǎn)變成為最終類,無(wú)法被繼承。
+ 在方法參數(shù)中使用final關(guān)鍵字:在方法內(nèi)部不能修改參數(shù)的值(在內(nèi)部中詳解)。
## 7.多態(tài)性
+ 方法的重寫(xiě)與重載就是方法的多態(tài)性表現(xiàn)
+ 多個(gè)子類就是父類中的多種形態(tài)
+ 父類引用可以指向子類對(duì)象,自動(dòng)轉(zhuǎn)換
+ 子類對(duì)象指向父類引用需要強(qiáng)制轉(zhuǎn)換(類型不對(duì)會(huì)報(bào)異常)
+ 在實(shí)際開(kāi)發(fā)中盡量使用父類引用(更利于擴(kuò)展)
## 8.instanceof關(guān)鍵字
是用于檢查對(duì)象是否為指定的類型,通常在把父類引用強(qiáng)制轉(zhuǎn)換為子類引用時(shí)要使用,以避免發(fā)生類型轉(zhuǎn)換異常(ClassCastException)。
# 七、抽象類、接口和異常
## 1.抽象類的基本概念
+ 很多具有相同特征和行為的對(duì)象可以抽象為一個(gè)類,很多具有相同特征和行為的類可以抽象為一個(gè)抽象類
+ 使用abstract關(guān)鍵字聲明的類為抽象類
+ 抽象類不能被實(shí)例化
## 2.抽象方法的基本概念
+ 在Java中,當(dāng)一個(gè)類的方法被abstract關(guān)鍵字修飾時(shí),該方法稱為抽象方法。抽象方法所在的類必須定義為抽象類。
+ 抽象方法沒(méi)有方法體。
## 2.接口
### 1)接口的使用規(guī)則
+ 定義一個(gè)接口使用interface關(guān)鍵字
+ 在一個(gè)接口中,只能定義常量、抽象方法,JDK1.8后可以定義默認(rèn)的實(shí)現(xiàn)方法
+ 接口可以繼承多個(gè)接口:extends xxx,xxx
+ 一個(gè)具體類實(shí)現(xiàn)接口使用implements關(guān)鍵字
+ 一個(gè)類可以實(shí)現(xiàn)多個(gè)接口
+ 抽象類實(shí)現(xiàn)接口可以不實(shí)現(xiàn)接口的方法
+ 在接口中定義的方法沒(méi)有聲明訪問(wèn)修飾符,默認(rèn)為public
+ 接口不能有構(gòu)造方法
+ 接口不能被實(shí)例化
### 2)面向?qū)ο笤O(shè)計(jì)原則
+ 對(duì)修改關(guān)閉,對(duì)擴(kuò)展開(kāi)放
+ 面向接口編程
## 3.oo原則總結(jié)
+ 開(kāi)閉原則:一個(gè)軟件實(shí)體如類、模塊和函數(shù)應(yīng)該對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。
+ 合成/聚合復(fù)用原則:新對(duì)象的某些功能在已創(chuàng)建好的對(duì)象里實(shí)現(xiàn),那么盡量用已有對(duì)象提供的功能,使之成為新對(duì)象的一部分,而不要再重新創(chuàng)建。
+ 依賴倒置原則:高層模塊不依賴底層模塊,二者都應(yīng)該依賴其抽象;抽象不應(yīng)該依賴細(xì)節(jié);細(xì)節(jié)應(yīng)該依賴抽象。
+ 接口隔離原則:客戶端不應(yīng)該依賴它不需要的接口,一個(gè)類對(duì)另一個(gè)類的依賴應(yīng)該建立在最小的接口之上。
+ 迪米特法則:一個(gè)對(duì)象應(yīng)該對(duì)其它對(duì)象保持最少的了解。
+ 里氏替換原則:所有引用基類的地方必須能夠透明地使用其子類對(duì)象。
+ 單一職責(zé)原則:不要存在多于一個(gè)導(dǎo)致類變更地原因,即一個(gè)類知負(fù)責(zé)一項(xiàng)原則。
## 4.抽象類與接口的異同點(diǎn)
相同點(diǎn):
+ 不能實(shí)例化對(duì)象,只能通過(guò)子類(實(shí)現(xiàn)類)對(duì)象指向指向自己的引用
+ 都可以有抽象方法、屬性
+ 都屬于父級(jí)元素
不同點(diǎn):
+ 接口的方法只能是抽象方法和靜態(tài)方法,抽象類可以有抽象方法,也可以沒(méi)有,其他類型的方法也都可以有
+ 接口中的屬性只能是公有靜態(tài)屬性(public static final),抽象類沒(méi)有限制
+ 本質(zhì)不同,一個(gè)是類,一個(gè)是接口
## 5.異常
### 1.異常的定義:
異常是指在程序的運(yùn)行過(guò)程中所發(fā)生的不正常的事件,它會(huì)中斷正在運(yùn)行的程序。
### 2.異常處理的五個(gè)關(guān)鍵字:
try、catch、finally、throws、throw
finally代碼塊只有在catch塊中有System.exit()時(shí)才不會(huì)執(zhí)行,其他任何情況都會(huì)執(zhí)行。

# 八、Object類和內(nèi)部類
## 1.Object類
每個(gè)類都是用Object類作為超類。所有對(duì)象(包括數(shù)組)都實(shí)現(xiàn)這個(gè)類的方法。
## 2.內(nèi)部類
### 1)成員內(nèi)部類
~~~java
public class Demo5 {
? ? public static void main(String[] args) {
? ? ? ? A a = new A();
? ? ? ? A.B b = a.new B();
? ? ? ? b.say();
? ? }
}
class A{
? ? private int num;
? ? class B{
? ? ? ? public void say(){
? ? ? ? ? ? System.out.println("我是內(nèi)部類");
? ? ? ? }
? ? }
}
~~~
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖8.1
~~~java
public class Demo5 {
? ? public static void main(String[] args) {
? ? ? ? A a = new A();
? ? ? ? a.printB();
? ? }
}
class A{
? ? private int num;
? ? public void printB(){
? ? ? ? B b = new B();
? ? ? ? b.say();
? ? }
? ? private class B{
? ? ? ? public void say(){
? ? ? ? ? ? System.out.println("我是成員內(nèi)部類");
? ? ? ? }
? ? }
}
~~~
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖8.2
上述兩份代碼皆為內(nèi)部類方法的調(diào)用,建議使用第二種。第二種封裝了內(nèi)部類,向外提供了使用內(nèi)部類的接口(方法)。
### 2)方法內(nèi)部類
+ 方法內(nèi)部類只能在定義該內(nèi)部類的方法內(nèi)進(jìn)行實(shí)例化,不可以在方法外進(jìn)行實(shí)例化。
+ 方法內(nèi)部類對(duì)象不能使用該內(nèi)部類所在方法的非final局部變量(jdk1.8之后一旦使用了沒(méi)有final修飾符的局部變量,該變量就成了就成了final變量,不能再修改其值)。
~~~java
public class Demo5 {
? ? public static void main(String[] args) {
? ? ? ? A a = new A();
? ? ? ? a.printB();
? ? ? ? a.method();
? ? }
}
class A{
? ? private int num;
? ? public void printB(){
? ? ? ? B b = new B();
? ? ? ? b.say();
? ? }
? ? private class B{
? ? ? ? public void say(){
? ? ? ? ? ? System.out.println("我是成員內(nèi)部類");
? ? ? ? }
? ? }
? ? public void method(){
? ? ? ? class C{
? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? System.out.println("我是方法內(nèi)部類");
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? C c = new C();
? ? ? ? c.say();
? ? }
}
~~~
### 3)靜態(tài)內(nèi)部類
靜態(tài)的含義是該內(nèi)部類可以像其它靜態(tài)成員一樣,沒(méi)有外部類對(duì)象時(shí),也能夠訪問(wèn)它。靜態(tài)內(nèi)部類僅能訪問(wèn)外部類的靜態(tài)成員和方法。
~~~java
public class Demo5 {
? ? public static void main(String[] args) {
? ? ? ? A a = new A();
? ? ? ? a.printB();
? ? ? ? a.method();
? ? ? ? A.D d = new A.D();
? ? ? ? d.say();
? ? }
}
class A{
? ? private int num;
? ? public void printB(){
? ? ? ? B b = new B();
? ? ? ? b.say();
? ? }
? ? private class B{
? ? ? ? public void say(){
? ? ? ? ? ? System.out.println("我是成員內(nèi)部類");
? ? ? ? }
? ? }
? ? public void method(){
? ? ? ? class C{
? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? System.out.println("我是方法內(nèi)部類");
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? C c = new C();
? ? ? ? c.say();
? ? }
? ? static class D{
? ? ? ? public void say(){
? ? ? ? ? ? System.out.println("我是靜態(tài)內(nèi)部類");
? ? ? ? }
? ? }
}
~~~
### 4)匿名內(nèi)部類
+ 繼承式匿名內(nèi)部類
? ~~~java
? public class Demo5 {
? ? ? public static void main(String[] args) {
? ? ? ? ? Cat cat = new Cat(){
? ? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? ? System.out.println("我是繼承式匿名內(nèi)部類");
? ? ? ? ? ? ? }
? ? ? ? ? };
? ? ? ? ? cat.say();
? ? ? }
? }
? abstract class Cat{
? ? ? abstract public void say();
? }
? ~~~
??
+ 接口式匿名內(nèi)部類
? ~~~java
? public class Demo5 {
? ? ? public static void main(String[] args) {
? ? ? ? ? Cat cat = new Cat(){
? ? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? ? System.out.println("我是繼承式匿名內(nèi)部類");
? ? ? ? ? ? ? }
? ? ? ? ? };
? ? ? ? ? cat.say();
??
? ? ? ? ? Icat cat1 = new Icat() {
? ? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? ? System.out.println("我是接口式匿名內(nèi)部類");
? ? ? ? ? ? ? }
? ? ? ? ? };
? ? ? ? ? cat1.say();
? ? ? }
? }
? abstract class Cat{
? ? ? abstract public void say();
? }
? interface Icat{
? ? ? void say();
? }
? ~~~
??
+ 參數(shù)式匿名內(nèi)部類
? ~~~java
? public class Demo5 {
? ? ? public static void main(String[] args) {
? ? ? ? ? Demo demo = new Demo();
? ? ? ? ? demo.say(new Icat() {
? ? ? ? ? public void say(){
? ? ? ? ? ? ? System.out.println("我是參數(shù)式匿名內(nèi)部類");
? ? ? ? ? }
? ? ? ? ? });
? ? ? }
? }
??
? interface Icat {
? ? ? void say();
? }
??
? class Demo {
? ? ? public void say(Icat icat) {
? ? ? ? ? icat.say();
? ? ? }
? }
??
? ~~~
??
### 5)使用匿名內(nèi)部類的原則:
? + 不能有構(gòu)造方法,只能由一個(gè)實(shí)例
? + 不能定義任何靜態(tài)成員、靜態(tài)方法(沒(méi)有類名)
? + 一定是跟在new的后面,用其隱含實(shí)現(xiàn)一個(gè)接口或繼承一個(gè)類
? + 匿名內(nèi)部類為局部的,所以局部?jī)?nèi)部類的所有限制都對(duì)其生效
### 6)內(nèi)部類的作用:
? 每個(gè)內(nèi)部類都能獨(dú)立地繼承自一個(gè)(接口地)實(shí)現(xiàn),所以無(wú)論外部類是否繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類都沒(méi)有影響。如果沒(méi)有內(nèi)部類提供的可以繼承多個(gè)具體的或抽象的類的能力,一些設(shè)計(jì)與編程問(wèn)題就很難解決。從這個(gè)角度看,內(nèi)部類使得多重繼承的解決方案變得完整。接口解決了部分問(wèn)題,而內(nèi)部類有效地實(shí)現(xiàn)了“多重繼承”。
# 九、數(shù)據(jù)結(jié)構(gòu)之鏈表
? ~~~java
? public class Demo5 {
? ? ? public static void main(String[] args) {
? ? ? ? ? NodeManager nodeManager = new NodeManager();
? ? ? ? ? nodeManager.add(5);
? ? ? ? ? nodeManager.add(4);
? ? ? ? ? nodeManager.add(3);
? ? ? ? ? nodeManager.print();
? ? ? ? ? System.out.println("刪除"+nodeManager.del(2));
? ? ? ? ? nodeManager.print();
? ? ? ? ? System.out.println("查找"+nodeManager.find(2));
? ? ? ? ? System.out.println("更新"+nodeManager.updata(4,6));
? ? ? ? ? nodeManager.print();
? ? ? ? ? nodeManager.insert(0,1);
? ? ? ? ? nodeManager.print();
? ? ? }
? }
??
? class NodeManager {
? ? ? private Node root; //根節(jié)點(diǎn)
? ? ? private int currentIndex = 0;
? ? ? public void add(int data) {
? ? ? ? ? if (root == null) {
? ? ? ? ? ? ? root = new Node(data);
? ? ? ? ? } else {
? ? ? ? ? ? ? root.addNode(data);
? ? ? ? ? }
? ? ? }
??
? ? ? public boolean del(int data) {
? ? ? ? ? if(root == null) return false;
? ? ? ? ? if (root.getData() == data) {
? ? ? ? ? ? ? root.next = root;
? ? ? ? ? ? ? return true;
? ? ? ? ? } else {
? ? ? ? ? ? ? return root.delNode(data);
? ? ? ? ? }
? ? ? }
??
? ? ? //打印所有
? ? ? public void print() {
? ? ? ? ? if (root != null) {
? ? ? ? ? ? ? System.out.print(root.getData() + " ");
? ? ? ? ? ? ? root.printNode();
? ? ? ? ? ? ? System.out.println();
? ? ? ? ? }
? ? ? }
??
? ? ? //查找是否存在節(jié)點(diǎn)
? ? ? public boolean find(int data) {
? ? ? ? ? if (root != null) {
? ? ? ? ? ? ? if (root.getData() == data) {
? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? return root.findNode(data);
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ? ? return false;
? ? ? }
??
? ? ? public boolean updata(int oldData, int newData) {
? ? ? ? ? if(root == null) return false;
? ? ? ? ? if(root.getData() == oldData){
? ? ? ? ? ? ? root.setData(newData);
? ? ? ? ? ? ? return true;
? ? ? ? ? }else {
? ? ? ? ? ? ? return root.updataNode(oldData,newData);
? ? ? ? ? }
? ? ? }
??
? ? ? public void insert(int index, int data) {
? ? ? ? ? if(index < 0)return;
? ? ? ? ? currentIndex = 0; //初始化
? ? ? ? ? if(index == currentIndex){
? ? ? ? ? ? ? Node newNode = new Node(data);
? ? ? ? ? ? ? newNode.next = root.next;
? ? ? ? ? ? ? root.next = newNode;
? ? ? ? ? }else {
? ? ? ? ? ? ? root.insertNode(index,data);
? ? ? ? ? }
? ? ? }
??
? ? ? class Node {
? ? ? ? ? private int data;
? ? ? ? ? private Node next;
??
? ? ? ? ? public Node(int data) {
? ? ? ? ? ? ? this.data = data;
? ? ? ? ? }
??
? ? ? ? ? public void setData(int data) {
? ? ? ? ? ? ? this.data = data;
? ? ? ? ? }
??
? ? ? ? ? public int getData() {
? ? ? ? ? ? ? return data;
? ? ? ? ? }
??
? ? ? ? ? //添加節(jié)點(diǎn)
? ? ? ? ? public void addNode(int data) {
? ? ? ? ? ? ? if (this.next == null) {
? ? ? ? ? ? ? ? ? this.next = new Node(data);
? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? this.next.addNode(data);
? ? ? ? ? ? ? }
? ? ? ? ? }
??
? ? ? ? ? //刪除節(jié)點(diǎn)
? ? ? ? ? public boolean delNode(int data) {
? ? ? ? ? ? ? if(this.next == null)return false;
? ? ? ? ? ? ? if (this.next.getData() == data) {
? ? ? ? ? ? ? ? ? this.next = this.next.next;
? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? return this.next.delNode(data);
? ? ? ? ? ? ? }
? ? ? ? ? }
??
? ? ? ? ? //打印所有節(jié)點(diǎn)
? ? ? ? ? public void printNode() {
? ? ? ? ? ? ? if (this.next != null) {
? ? ? ? ? ? ? ? ? System.out.print(this.next.getData() + " ");
? ? ? ? ? ? ? ? ? this.next.printNode();
? ? ? ? ? ? ? }
? ? ? ? ? }
??
? ? ? ? ? //查找節(jié)點(diǎn)是否存在
? ? ? ? ? public boolean findNode(int data) {
? ? ? ? ? ? ? if (this.next != null) {
? ? ? ? ? ? ? ? ? if (this.next.getData() == data) {
? ? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? return this.next.findNode(data);
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? }
? ? ? ? ? ? ? return false;
? ? ? ? ? }
??
? ? ? ? ? //修改節(jié)點(diǎn)
? ? ? ? ? public boolean updataNode(int oldData, int newData) {
? ? ? ? ? ? ? if(this.next == null) return false;
? ? ? ? ? ? ? if(this.next.getData() == oldData){
? ? ? ? ? ? ? ? ? this.next.setData(newData);
? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? ? return this.next.updataNode(oldData,newData);
? ? ? ? ? ? ? }
? ? ? ? ? }
??
? ? ? ? ? //插入節(jié)點(diǎn)
? ? ? ? ? public void insertNode(int index, int data) {
? ? ? ? ? ? ? currentIndex++;
? ? ? ? ? ? ? if(index == currentIndex){
? ? ? ? ? ? ? ? ? Node newNode = new Node(data);
? ? ? ? ? ? ? ? ? newNode.next = this.next.next;
? ? ? ? ? ? ? ? ? this.next.next = newNode;
? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? ? this.next.insertNode(index, data);
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? }
? }
??
? ~~~
??
# ? 十、基本數(shù)據(jù)類型包裝類
## 1.裝箱及拆箱操作
將一個(gè)基本數(shù)據(jù)類型轉(zhuǎn)換為包裝類,那么這樣的操作稱為裝箱操作。將一個(gè)包裝類轉(zhuǎn)換為基本數(shù)據(jù)類型,這樣的操作稱為拆箱操作。
~~~java
public class Demo1 {
? ? //將基本數(shù)據(jù)類型轉(zhuǎn)換為包裝類,稱為自動(dòng)裝箱
? ? Integer i1 = new Integer(10);
? ? //將包裝類轉(zhuǎn)換為基本數(shù)據(jù)類型,稱為自動(dòng)拆箱
? ? int i2 = i1.intValue();
? ? Integer i3 = 10; //建議方式
? ? Integer i4 = new Integer("123");
? ? //把數(shù)值字符串轉(zhuǎn)換為int類型
? ? String num1 = "12";
? ? int i5 = Integer.parseInt(num1);
? ? Integer i6 = Integer.valueOf(num1);
? ? int i7 = Integer.valueOf(num1); //自動(dòng)拆箱
}
~~~
# 十一、常用類庫(kù)
## 1.String類
+ String類可以表示一個(gè)字符串
+ **String類實(shí)際上是用字符數(shù)組存儲(chǔ)的**
+ 使用final修飾,不能被繼承
### 1)String類的兩種賦值方式:
~~~java
//直接賦值
String name1 = "小白";
//通過(guò)關(guān)鍵字new調(diào)用String的構(gòu)造方法賦值
//下面的代碼會(huì)創(chuàng)建兩個(gè)對(duì)象(如果常量池中沒(méi)有小黑,就會(huì)在常量池中創(chuàng)建這個(gè)對(duì)象,然后通過(guò)new再在堆中創(chuàng)建一個(gè)小黑對(duì)象
String name2 = new ?String("小黑");
~~~
### 2)直接賦值字符串連接的4種情況:
考慮編譯期和運(yùn)行期,如果代碼在編譯期就可以被確定,那么就使用已有的對(duì)象,否則會(huì)在運(yùn)行其創(chuàng)建新的對(duì)象。
~~~java
public class Demo1 {
? ? public static void main(String[] args) {
? ? ? ? //結(jié)果為false
? ? ? ? String a = "a"; ?
? ? ? ? String a1 = a+1; ?//在編譯期a1看到的a是變量所以a1不能確定
? ? ? ? String a2 = "a1";
? ? ? ? System.out.println(a1 == a2);
? ? ? ??
? ? ? ? //結(jié)果為true
? ? ? ? final String b = "b"; ?
? ? ? ? String b1 = b+1; ?//b被申明為常量,b1在編譯期可以確定
? ? ? ? String b2 = "b1";
? ? ? ? System.out.println(b1 == b2);
? ? ? ??
? ? ? ? //結(jié)果為false
? ? ? ? String c = getC(); ?
? ? ? ? String c1 = getC() + 1; ?//方法只有在運(yùn)行期才被調(diào)用,所以c1的值也無(wú)法確定,要在運(yùn)行期在堆中用new創(chuàng)建
? ? ? ? String c2 = "c2";
? ? ? ??
? ? ? ? //結(jié)果為false
? ? ? ? final String d = getD(); ?
? ? ? ? String d1 = getD() + 1; ?//原因同第3種
? ? ? ? String d2 = "d2";
? ? }
? ? private static String getC(){
? ? ? ? return "c";
? ? }
? ? private static String getD(){
? ? ? ? return "d";
? ? }
}
~~~
### ? 3)String類的常用方法
#### ①String類字符與字符串操作方法
+ 普通方法 public char charAt(int intdex) ?根據(jù)下標(biāo)找到指定的字符
+ 普通方法 public char [] toCharArray() 以字符數(shù)組的形式返回字符串的全部?jī)?nèi)容
+ 構(gòu)造方法 public String (char [] value) ?將全部的字符數(shù)組變?yōu)樽址?br /> + 構(gòu)造方法 public String (char [],int offset,int count) 將指定范圍內(nèi)的字符數(shù)組變?yōu)樽址?/p>
#### ②String類字節(jié)與字符串操作方法
+ 普通方法 public byte [] getBytes() 將字符串變?yōu)樽止?jié)數(shù)組
+ 構(gòu)造方法 public String(byte [] bytes) 將字節(jié)數(shù)組變?yōu)樽址?br /> + 構(gòu)造方法 public String(byte [] bytes,int offset,int count) 將指定范圍內(nèi)的字節(jié)數(shù)組變?yōu)樽址?br /> + 構(gòu)造方法 public String(byte [] bytes,String charsetName) 通過(guò)使用指定的charset解碼指定的byte數(shù)組,構(gòu)造一個(gè)新的String對(duì)象
將字節(jié)數(shù)組轉(zhuǎn)換為字符數(shù)組:
~~~java
? ? ? ? String s = "小黑";
? ? ? ? System.out.println(s.toCharArray());
? ? ? ? System.out.println(Arrays.toString(s.getBytes()));
~~~
#### ③String類判斷是否以指定內(nèi)容開(kāi)頭或結(jié)尾
+ 普通方法 public boolean startWith(String prefix) 從第一個(gè)位置開(kāi)始判斷是否以指定的內(nèi)容開(kāi)頭
+ 普通方法 public boolean startWith(String prefix,int toffset) 從指定的位置開(kāi)始判斷是否以指定的內(nèi)容開(kāi)頭
+ 普通方法 public boolean endWith(String suffix) ?判斷是否以指定的內(nèi)容結(jié)尾
#### ④String類替換操作
+ 普通方法 public String replace(char oldChar,char newChar) ?替換指定字符
+ 普通方法 public String replace(CharSequence target,CharSequence replacement) ?替換指定字符串
+ 普通方法 public String replaceAll(String regex,String replacement) ?替換指定的字符串
+ 普通方法 public String replaceFirst(String regex,String replacement) 替換第一個(gè)滿足條件的字符串
#### ⑤String類字符串截取操作
+ 普通方法 public String subString(int beginIndex) 從指定位置開(kāi)始一直截取到末尾
+ 普通方法 public String subString(int beginIndex,int endIndex) 截取指定范圍內(nèi)的字符串
#### ⑥String類字符串拆分操作
+ 普通方法 public [] String spit(String regex) ?按照指定的字符串拆分
+ 普通方法 public [] String ?spit(String regex,int limit) ?拆分字符串,并指定拆分的個(gè)數(shù)
#### ⑦String類字符串查找操作
+ 普通方法 public boolean contains(String s) ?返回一個(gè)字符串是否存在
+ 普通方法 public int indexOf(int ch) 從頭查找指定的字符是否存在,char->int,如果存在則返回位置,不存在則返回“-1”
+ 普通方法 public int indexOf(int ch,int fromIndex) 從指定位置查找指定的字符是否存在,char->int,如果存在則返回位置,不存在則返回“-1”
+ 普通方法 public int indexOf(String str) 從頭查找指定的字符串是否存在,如果存在則返回位置,不存在則返回“-1”
+ 普通方法 public int indexOf(String str,int fromIndex) 從指定位置查找指定的字符串,如果存在則返回位置,不存在則返回“-1”
+ 普通方法 public int lastindexOf(int ch) 從字符串的最后向前查找指定的字符是否存在,char->int,如果存在則返回位置,不存在則返回“-1”
+ 普通方法 public int lastindexOf(int ch,int fromIndex) 從指定的末尾向前查找指定的字符是否存在,char->int,如果存在則返回位置,不存在則返回“-1”
+ 普通方法 public int lastindexOf(String str) 從字符串的最后向前查找指定的字符串是否存在,如果存在則返回位置,不存在則返回“-1”
+ 普通方法 public int lastindexOf(String str,int fromIndex) 從指定的末尾向前查找指定的字符串,如果存在則返回位置,不存在則返回“-1”
#### ⑧String類的其它操作方法
+ 普通方法 public boolean isEmpty() ?判斷字符串的內(nèi)容是否為空,**不是null**
+ 普通方法 public int length() 取得字符串的長(zhǎng)度
+ 普通方法 public String toLowerCase() ?轉(zhuǎn)小寫(xiě)
+ 普通方法 public String toUpperCase() 轉(zhuǎn)大寫(xiě)
+ 普通方法 public String trim() 去掉開(kāi)頭和結(jié)尾的空格,中間的空個(gè)不去
+ 普通方法 public String concat(String str) 字符串連接操作
## 2.StringBuffer類
### 1)StringBuffer介紹
使用String連接字符串,代碼性能會(huì)非常低,因?yàn)镾tring的內(nèi)容不可變。StringBuffer使用動(dòng)態(tài)數(shù)組的方式擴(kuò)充數(shù)組,使得StringBuffer對(duì)象的內(nèi)容是可變的,有效地解決了連接字符串時(shí)代碼性能低的問(wèn)題。
### 2)StringBuffer常用操作方法
+ 構(gòu)造方法 public StringBuffer() ?構(gòu)造一個(gè)空的StringBuffer對(duì)象
+ 構(gòu)造方法 public StringBuffer(String str) ?將指定的String變?yōu)镾tringBuffer的內(nèi)容
+ 構(gòu)造方法 public StringBuffer(CharSequence ?seq) ?接收CharSequence接口的實(shí)例
+ 普通方法 public StringBuffer append(數(shù)據(jù)類型 b) ? 提供了很多append()方法,用于進(jìn)行字符串連接
+ 普通方法 public StringBuffer delete(int start,int end) ? 刪除指定位置的內(nèi)容
+ 普通方法 public int indexOf(String str) ? 字符串的查詢功能
+ 普通方法 public StringBuffer insert(int offset,數(shù)據(jù)類型 b) ? 在指定位置增加一個(gè)內(nèi)容
+ 普通方法 public StringBuffer replace(int start,int end,String str) ?將指定范圍內(nèi)的內(nèi)容替換成其它內(nèi)容
+ 普通方法 public String substring(int start,int end) ?截取指定范圍內(nèi)的字符串
+ 普通方法 public String substring(int start) ?字符串截取
+ 普通方法 public StringBuffer reverse() 字符串反轉(zhuǎn)
## 3.StringBuilder類
StringBuilder介紹
一個(gè)可變的字符序列。此類提供了與StringBuffer兼容的API,但不保證同步。該類被設(shè)計(jì)用作StringBuffer的一個(gè)簡(jiǎn)易替換,用在字符緩沖區(qū)被單個(gè)線程使用的時(shí)候(這種情況很普遍)。如果可能,建議先采用該類,因?yàn)樵诖蠖鄶?shù)的實(shí)現(xiàn)中,它比StringBuffer要快。
## 4.Math與Random類
### 1)Math類的常用方法:
+ abs(double a) ?返回double值的絕對(duì)值
+ random() ? 返回帶正號(hào)的double值,該值大于等于0.0且小于1.0
+ round(double a) ?返回最接近參數(shù)并且等于某一整數(shù)的double值
+ sqrt(double) ? 返回正確舍入的double值的平方根
### 2)Random類的常用方法
此類的實(shí)例用于生成偽隨機(jī)數(shù)流
+ nextLong() ? 返回下一個(gè)偽隨機(jī)數(shù)的long值
+ nextBoolean() ?返回下一個(gè)偽隨機(jī)數(shù)的boolean值、
+ nextDouble() ? 返回下一個(gè)偽隨機(jī)數(shù),在0.0和1.0之間的double值
+ nextFloat() ? 返回下一個(gè)偽隨機(jī)數(shù),在0.0和1.0之間的float值
+ nextInt() ?返回下一個(gè)偽隨機(jī)數(shù)的int值
+ nextInt(int n) ? 返回下一個(gè)偽隨機(jī)數(shù),在0(包括)和指定值分布的int值
## 5.日期操作類
### 1)Date類
類Date表示特定的瞬間,精確到毫秒,也就是程序運(yùn)行時(shí)的當(dāng)前時(shí)間。
~~~java
Date date = new Date(); ?//實(shí)例化Date對(duì)象,表示當(dāng)前時(shí)間
~~~
### 2)Calendar類(抽象類)
日歷類,使用此類可以將時(shí)間精確到毫秒顯示
~~~java
//兩種實(shí)例化方式
Calendar c1 = Calendar.getInstance();
Calendar c2 = new GregorianCalendar();?
int year = c1.get(Calendar.YEAR) ?//獲取當(dāng)前時(shí)間的年份
int month = c1.get(Calendar.MONTH) //獲取當(dāng)前時(shí)間的月份
int day = c1.get(Calendar.DAY_OF_MONTH) //獲取當(dāng)前時(shí)間的天數(shù)
int hour = c1.get(Calendar.HOUR_OF_DAY) ?//獲取當(dāng)前時(shí)間的小時(shí)數(shù)
int minute = c1.get(Calendar.MINUTE) ?//獲取當(dāng)前時(shí)間的分鐘數(shù)
int second = c1.get(Calendar.SECOND) ? //獲取當(dāng)前時(shí)間的秒數(shù)
int millisecond = c1.get(Calendar.MILLISECOND) ?//獲取當(dāng)前時(shí)間的毫秒數(shù)
~~~
### 3)DateFormat類及子類SimpleDateFormat
格式化日期的表示形式
~~~java
DateFormat df = new SimpleDateFormat("yyyy年MM月dd日HH:MM:ss SSS");
String nowData = df.format(new Date());
System.out.println(nowData);
~~~
## 6.Comparable與Comparator
### 1)Comparable接口
此接口強(qiáng)行對(duì)實(shí)現(xiàn)它的每個(gè)類的對(duì)象進(jìn)行整體排序。這種排序被稱為類的自然排序,類的compareTo方法被稱為他的自然比較方法。
### 2)Comparator接口
Comparable接口是要求自定義類去實(shí)現(xiàn),按照oo原則,對(duì)修改關(guān)閉,對(duì)擴(kuò)展開(kāi)放。Comparator接口強(qiáng)行對(duì)某個(gè)對(duì)象collection進(jìn)行整體排序的比較。
## 7.Cloneable(對(duì)象的克隆)
將一個(gè)對(duì)象復(fù)制一份,稱為對(duì)象的克隆技術(shù)。
在Object類中存在一個(gè)clone()方法:protected Object clone() throws CloneNotSupportedException?
如果某個(gè)類的對(duì)象想要被克隆,則對(duì)象所在的類必須實(shí)現(xiàn)Cloneable接口。此接口沒(méi)有定義任何方法,是一個(gè)標(biāo)記接口。
~~~java
public class Test {
? ? public static void main(String[] args) throws CloneNotSupportedException {
? ? ? ? Cat cat = new Cat("咪咪",2);
? ? ? ? Cat newCat = (Cat) cat.clone();
? ? ? ? System.out.println(cat);
? ? ? ? System.out.println(newCat);
? ? ? ? System.out.println(cat==newCat);
? ? }
}
class Cat implements Cloneable {
? ? private String name;
? ? private int age;
? ? public Cat() {
? ? }
? ? public Cat(String name, int age) {
? ? ? ? this.name = name;
? ? ? ? this.age = age;
? ? }
? ? public String getName() {
? ? ? ? return name;
? ? }
? ? public void setName(String name) {
? ? ? ? this.name = name;
? ? }
? ? public int getAge() {
? ? ? ? return age;
? ? }
? ? public void setAge(int age) {
? ? ? ? this.age = age;
? ? }
? ? @Override
? ? public String toString() {
? ? ? ? return "Cat{" +
? ? ? ? ? ? ? ? "name='" + name + '\'' +
? ? ? ? ? ? ? ? ", age=" + age +
? ? ? ? ? ? ? ? '}';
? ? }
? ? @Override
? ? protected Object clone() throws CloneNotSupportedException {
? ? ? ? return super.clone();
? ? }
}
~~~
## 8.System與Runtime類
### 1)System類
System代表系統(tǒng),系統(tǒng)級(jí)的很多屬性和控制方法都放置在該類的內(nèi)部。該類位于java.lang包。
+ **成員變量**:System類內(nèi)部包含in、out和err三個(gè)成員變量,分別代表標(biāo)準(zhǔn)輸入流(鍵盤(pán)輸入),標(biāo)準(zhǔn)輸出流(顯示器)和標(biāo)準(zhǔn)錯(cuò)誤輸出流。
+ **成員方法**:
? public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length) ?該方法的作用是數(shù)組拷貝,也就是將一個(gè)數(shù)組中的內(nèi)容復(fù)制到另一個(gè)數(shù)組中的指定位置,由于該方法時(shí)native方法,所以性能上比使用循環(huán)高效。
? public static long currentTimeMillis() ?該方法的作用時(shí)返回計(jì)算機(jī)的當(dāng)前時(shí)間,時(shí)間的表達(dá)格式和GMT(格林威治時(shí)間)所差的的毫秒數(shù)。
? public static void exit(int status) ?該方法的作用是退出程序。其中status的值為0代表正常退出,非零代表異常退出
? public static void gc() ? 該方法的作用時(shí)請(qǐng)求系統(tǒng)進(jìn)行垃圾回收。至于系統(tǒng)是否回收垃圾,則取決于系統(tǒng)中垃圾回收算法的實(shí)現(xiàn)以及系統(tǒng)執(zhí)行時(shí)的情況。
? public static String getProperty(String key) ?該方法的作用是獲得系統(tǒng)中屬性名為key的屬性對(duì)應(yīng)的值。
? ~~~java
? int [] num1 = {1,2,3,4};
? int [] num2 = new int[5];
? //參數(shù):源數(shù)組,源數(shù)組的起始位置,目標(biāo)數(shù)組,目標(biāo)數(shù)組的起始位置,復(fù)制的長(zhǎng)度
? System.arraycopy(num1,0,num2,1,num1.length);
? System.out.println(Arrays.toString(num2));
? System.out.println(System.currentTimeMillis());
? ~~~
### 2)Runtime類
每個(gè)應(yīng)用程序都有一個(gè)Runtime的實(shí)例,使應(yīng)用程序能夠與其運(yùn)行的環(huán)境連接。
~~~java
//獲取java運(yùn)行時(shí)相關(guān)的運(yùn)行時(shí)對(duì)象
? ? ? ? Runtime rt = Runtime.getRuntime();
? ? ? ? System.out.println("處理器數(shù)量:"+rt.availableProcessors()+"個(gè)");
? ? ? ? System.out.println("Jvm總內(nèi)存數(shù):"+rt.totalMemory()+"byte");
? ? ? ? System.out.println("Jvm空閑內(nèi)存數(shù):"+rt.freeMemory()+"byte");
? ? ? ? System.out.println("Jvm可用最大內(nèi)存數(shù):"+rt.maxMemory()+"byte");
? ? ? ? //在單獨(dú)的進(jìn)程中執(zhí)行指定的字符串命令
? ? ? ? rt.exec("notepad");
~~~
## 9.數(shù)字處理工具類
### 1)BigInteger
可以讓超過(guò)integer范圍內(nèi)的數(shù)據(jù)進(jìn)行運(yùn)算
~~~java
String val1 = "12374456546415165";
String val2 = "3498745983578590454";
BigInteger b1 = new BigInteger(val1);
BigInteger b2 = new BigInteger(val2);
b1.add(b2); ?//加
b1.subtract(b2); ?//減
b1.multiply(b2); ?//乘
b1.divide(b2); ?//除
b1.remainder(b2); ?//取余
b1.divideAndRemainder(b2); ?//除和取余,返回一個(gè)數(shù)組
~~~
### 2)BigDecimal
由于在運(yùn)算的時(shí)候,float和double很容易丟失精度,為了能精確的表示,計(jì)算浮點(diǎn)數(shù),java提供了BigDecimal,不可變的、任意精度的有符號(hào)十進(jìn)制數(shù)。
~~~java
String val3 = "123.7445654641516545";
String val4 = "349.8745983578590454";
BigInteger b3 = new BigInteger(val3);
BigInteger b4 = new BigInteger(val4);
b3.add(b4); ?//加
b3.subtract(b4); ?//減
b3.multiply(b4); ?//乘
b3.divide(b4); ?//除,可能會(huì)有除不盡的情況發(fā)生,這時(shí)會(huì)報(bào)異常 ,解決辦法是:b3.scale()-b4.scale()
b3.remainder(b4); ?//取余
b3.divideAndRemainder(b4); ?//除和取余,返回一個(gè)數(shù)組
~~~
### 3)DecimalFormat
java提供DecimalFormat類,幫你快速用最快的速度將數(shù)字格式化為你需要的樣子。
~~~java
double pi = 3.1415927;
//取一位整數(shù),結(jié)果是3
System.out.println(new DecimalFormat("0").format(pi));
//取一位整數(shù)和兩位小數(shù),結(jié)果是3.14
System.out.println(new DecimalFormat("0.00").format(pi));
//取兩位整數(shù)和三位小數(shù),整數(shù)不足部分以0填補(bǔ),結(jié)果是:03.142
System.out.println(new DecimalFormat("00.000").format(pi));
//取所有整數(shù)部分,結(jié)果為:3
System.out.println(new DecimalFormat("#").format(pi));
//以百分比方式計(jì)數(shù),并取兩位小數(shù),結(jié)果為:314.16%
System.out.println(new DecimalFormat("#.##%").format(pi));
~~~
## 10.MD5工具類
MD5的全稱是Message-DigestAlgorithm(信息摘要算法)
~~~java
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
public class Demo {
? ? static String savePassword = "4QrcOUm6Wau+VuBX8g+IPg==";
? ? public static void main(String[] args) {
? ? ? ? login("123456");
? ? }
? ? public static void login(String password){
? ? ? ? if(savePassword.equals(md5(password))){
? ? ? ? ? ? System.out.println("登錄成功!");
? ? ? ? }else {
? ? ? ? ? ? System.out.println("登錄失敗!");
? ? ? ? }
? ? }
? ? public static String md5(String password){
? ? ? ? try {
? ? ? ? ? ? MessageDigest md = MessageDigest.getInstance("md5");
? ? ? ? ? ? //通過(guò)MD5計(jì)算摘要
? ? ? ? ? ? byte[] bytes = new byte[0];
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? bytes = md.digest(password.getBytes("UTF-8"));
? ? ? ? ? ? } catch (UnsupportedEncodingException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? ? ? //System.out.println(Arrays.toString(bytes));
? ? ? ? ? ? // a-z A-Z 0-9 /* ?BASE64編碼算法
? ? ? ? ? ? String str = Base64.getEncoder().encodeToString(bytes); ?//加密后的密碼
? ? ? ? ? ? //System.out.println(str);
? ? ? ? ? ? return str;
? ? ? ? } catch (NoSuchAlgorithmException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? ? ? return null;
? ? }
}
~~~
## 11.數(shù)據(jù)結(jié)構(gòu)之二叉樹(shù)實(shí)現(xiàn)
### 1)簡(jiǎn)介
樹(shù)是一種重要的非線性數(shù)據(jù)結(jié)構(gòu),直觀地看,它是數(shù)據(jù)元素(在樹(shù)中稱為節(jié)點(diǎn))按分支關(guān)系組織起來(lái)的結(jié)構(gòu)。二叉樹(shù)是每個(gè)節(jié)點(diǎn)最多有兩個(gè)子樹(shù)的有序樹(shù)。通常子樹(shù)被稱為”左子樹(shù)“和”右子樹(shù)“。
### 2)二叉樹(shù)算法的排序規(guī)則
+ 選擇第一個(gè)元素作為根節(jié)點(diǎn)
+ 之后如果元素大于根節(jié)點(diǎn)放在右子樹(shù),小于根節(jié)點(diǎn)則放在左子樹(shù)
+ 最后按照中序遍歷的方式進(jìn)行輸出
~~~java
public class Demo {
? ? public static void main(String[] args) {
? ? ? ? BinaryTree binaryTree = new BinaryTree();
? ? ? ? binaryTree.add(1);
? ? ? ? binaryTree.add(2);
? ? ? ? binaryTree.add(3);
? ? ? ? binaryTree.add(4);
? ? ? ? binaryTree.add(5);
? ? ? ? binaryTree.print();
? ? }
}
class BinaryTree {
? ? //private int data;
? ? private Node root;
? ? public BinaryTree(){}
? ? public void add(int data) {
? ? ? ? if (root == null) {
? ? ? ? ? ? root.data = data;
? ? ? ? }else {
? ? ? ? ? ? root.addNode(data);
? ? ? ? }
? ? }
? ? public void print() {
? ? ? ? root.printNode();
? ? }
? ? class Node {
? ? ? ? private int data;
? ? ? ? private Node left;
? ? ? ? private Node right;
? ? ? ? public Node() {}
? ? ? ? public Node(int data) {
? ? ? ? ? ? this.data = data;
? ? ? ? }
? ? ? ? public void addNode(int data) {
? ? ? ? ? ? if (this.data > data) {
? ? ? ? ? ? ? ? if (this.right == null) {
? ? ? ? ? ? ? ? ? ? this.right.data = data;
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? this.right.addNode(data);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? if (this.left == null) {
? ? ? ? ? ? ? ? ? ? this.left.data = data;
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? this.left.addNode(data);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? public void printNode() {
? ? ? ? ? ? if (this.left != null) {
? ? ? ? ? ? ? ? this.left.printNode();
? ? ? ? ? ? }
? ? ? ? ? ? System.out.print(this.data + "->");
? ? ? ? ? ? if (this.right != null) {
? ? ? ? ? ? ? ? this.right.printNode();
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
~~~
# 十二、文件與IO
## 1.File類的使用
### ?1)File類的基本概念
+ File類:表示文件和目錄路徑名的抽象表示形式
+ File類可以實(shí)現(xiàn)文件的創(chuàng)建、刪除、重命名、得到路徑、創(chuàng)建時(shí)間等等,是唯一與文件本身有關(guān)的操作類。
### 2)File類的操作方法
+ public static final String separator ? 表示路徑分隔符
+ public File(String pathname) ? 構(gòu)造File類實(shí)例,要傳入路徑
+ public boolean creatNewFile() ?創(chuàng)建新文件
+ public boolean delete() ?刪除文件,文件夾中有文件時(shí)刪除不了,得清空文件夾才能刪除
+ public boolean isFile() ? 判斷給定的路徑是否是文件
+ public String [] list() ?列出文件夾中文件,字符串?dāng)?shù)組的形式
+ public File [] listFiles() 列出文件夾中的所有文件,返回文件數(shù)組
+ public boolean mkdir() ?創(chuàng)建新的文件夾
+ public boolean reanmeTo(File dest) ?為文件重命名并且移動(dòng)到指定的路徑處,等同于剪切并復(fù)制
+ public long length() ?返回文件的大小
~~~java
package com.demo;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class Test {
? ? public static void main(String[] args) {
? ? ? ? File f1 = new File("F://ideaspace//test//src//com//demo//test.text");
? ? ? ? if(!f1.exists()){
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? f1.createNewFile();
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // 是否為文件夾:f.isDirectory()
? ? ? ? System.out.println("是否為文件"+f1.isFile());
? ? ? ? File f2 = new File("F://ideaspace");
? ? ? ? String [] names = f2.list();
? ? ? ? System.out.println(Arrays.toString(names));
? ? ? ? File [] fs = f2.listFiles();
? ? ? ? for (File f3 : fs) {
? ? ? ? ? ? System.out.println("length="+f3.length());
? ? ? ? ? ? System.out.println("name="+f3.getName());
? ? ? ? ? ? System.out.println("相對(duì)路徑="+f3.getPath());
? ? ? ? ? ? System.out.println("絕對(duì)路徑= "+f3.getAbsolutePath());
? ? ? ? ? ? System.out.println("是否為隱藏文件="+f3.isHidden());
? ? ? ? ? ? System.out.println("是否為可讀文件="+f3.canRead());
? ? ? ? ? ? Date date = new Date(f3.lastModified());
? ? ? ? ? ? DateFormat dateFormat = new SimpleDateFormat("yyyy:MM:dd:HH:mm:ss");
? ? ? ? ? ? System.out.println("文件最后修改時(shí)間="+dateFormat.format(date));
? ? ? ? ? ? System.out.println("------------------------------------");
? ? ? ? }
? ? ? ? //返回指定后綴名的文件數(shù)組
? ? ? ? File [] files =f2.listFiles(new FileFilter() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean accept(File pathname) {
? ? ? ? ? ? ? ? return pathname.getName().endsWith(".txt");
? ? ? ? ? ? }
? ? ? ? });
? ? }
}
~~~
### 3)指定目錄查找文件示例
~~~java
package com.demo;
import java.io.File;
public class Test1 {
? ? public static void main(String[] args) {
? ? ? ? findFile(new File("F://ideaspace"),"java");
? ? }
? ? public static void findFile(File target,String ext){
? ? ? ? if(target == null)return;
? ? ? ? if(target.isDirectory()){
? ? ? ? ? ? File [] files = target.listFiles();
? ? ? ? ? ? if(files != null){
? ? ? ? ? ? ? ? for (File f : files) {
? ? ? ? ? ? ? ? ? ? findFile(f,ext);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }else {
? ? ? ? ? ? if(target.getName().toLowerCase().endsWith(ext));
? ? ? ? ? ? System.out.println(target.getAbsolutePath());
? ? ? ? }
? ? }
}
~~~
## 2.IO流
+ 概述:IO流是輸入輸出流。流是一組有序的,有起點(diǎn)和終點(diǎn)的字節(jié)集合,是對(duì)數(shù)據(jù)傳輸?shù)目偡Q或抽象。即數(shù)據(jù)在兩設(shè)備間的傳輸稱為流。流的本質(zhì)是數(shù)據(jù)傳輸,根據(jù)數(shù)據(jù)傳輸特性將流抽象為各種類,方便更直觀地進(jìn)行數(shù)據(jù)操作。
+ IO流地分類:根據(jù)處理數(shù)據(jù)類型地不同分為:字符流和字節(jié)流;根據(jù)流向不同分為:輸出流和輸入流。
### 1)字節(jié)輸入輸出流
#### ①字節(jié)輸出流
OutputStream類定義
public abstract class OutputStream extends Object implements Closeable,Flushable
此抽象類是表示輸出字節(jié)流的所有類的超類。輸出流接受輸出字節(jié)并將這些字節(jié)發(fā)送到InputStream類某個(gè)接收器要向文件中輸出,使用FileOutputStream類
#### ②字節(jié)輸入流
public abstract class IutputStream extends Object implements Closeable
此抽象類是表示字節(jié)輸入流的所有類的超類
FileInputStream從文件系統(tǒng)中的某個(gè)文件獲得輸入字節(jié)
~~~java
package com.demo;
import java.io.*;
public class Test2 {
? ? public static void in(){
? ? ? ? File f2 = new File("F://ideaspace//test//src//com//demo//test.text");
? ? ? ? try {
? ? ? ? ? ? InputStream in = new FileInputStream(f2);
? ? ? ? ? ? byte[] bytes = new byte[1024];
? ? ? ? ? ? StringBuilder stringBuilder = new StringBuilder();
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? int len = in.read(bytes);
? ? ? ? ? ? ? ? while (len != -1){
? ? ? ? ? ? ? ? ? ? stringBuilder.append(new String(bytes,0,len));
? ? ? ? ? ? ? ? ? ? len = in.read(bytes);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? in.close();
? ? ? ? ? ? ? ? System.out.println(stringBuilder);
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? public static void out(){
? ? ? ? File f1 = new File("F://ideaspace//test//src//com//demo//test.text");
? ? ? ? try {
? ? ? ? ? ? OutputStream out = new FileOutputStream(f1,true);
? ? ? ? ? ? String info = "獨(dú)開(kāi)眾卉已凋謝,不畏風(fēng)霜向晚欺\r\n";
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? out.write(info.getBytes());
? ? ? ? ? ? ? ? out.close();
? ? ? ? ? ? ? ? System.out.println("成功寫(xiě)入!");
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? public static void main(String[] args) {
? ? ? ? //out();
? ? ? ?in();
? ? }
}
~~~
### 2)字符輸入輸出流
#### ①Writer
寫(xiě)入字符流抽象類。子類必須實(shí)現(xiàn)的方法有write(char[],int,int)、flush()、close()。但是,多數(shù)子類將重寫(xiě)此處定義的一些方法,以提供更高的效率和/或其它功能。 ?與OutputStream一樣,對(duì)文件的操作使用:FileWriter完成。
#### ②Reader
用于讀取字符的抽象類。子類必須實(shí)現(xiàn)的方法有read(char[],int,int)和close()。但是,多數(shù)子類將重寫(xiě)此處定義的一些方法,以提供更高的效率和/或其它功能。與InputStream一樣,對(duì)文件的操作使用:FileReader完成。
~~~java
package com.demo;
import java.io.*;
public class Test3 {
? ? public static void out(){
? ? ? ? try {
? ? ? ? ? ? Writer out = new FileWriter(new File("F://ideaspace//test//src//com//demo//test.text"),true);
? ? ? ? ? ? out.write("掃碼領(lǐng)紅包\r\n");
? ? ? ? ? ? out.close();
? ? ? ? ? ? System.out.println("寫(xiě)入成功");
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? public static void in(){
? ? ? ? try {
? ? ? ? ? ? Reader in = new FileReader(new File("F://ideaspace//test//src//com//demo//test.text"));
? ? ? ? ? ? char[] chars = new char[3];
? ? ? ? ? ? StringBuilder stringBuilder = new StringBuilder();
? ? ? ? ? ? int len = -1;
? ? ? ? ? ? while ((len = in.read(chars)) != -1){
? ? ? ? ? ? ? ? stringBuilder.append(chars,0,len);
? ? ? ? ? ? }
? ? ? ? ? ? in.close();
? ? ? ? ? ? System.out.println(stringBuilder);
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? public static void main(String[] args) {
// ? ? ? ?out();
? ? ? ? in();
? ? }
}
~~~
### 3)文件復(fù)制示例
~~~java
package com.demo;
import java.io.*;
public class Test4 {
? ? public static void main(String[] args) {
? ? ? ? copy("F://ideaspace//test//src//com//demo//test.text","F://ideaspace//test//src//com//demo//test1.text");
? ? }
? ? public static void copy(String src,String target){
? ? ? ? File srcFile = new File(src);
? ? ? ? File targetFile = new File(target);
? ? ? ? try {
? ? ? ? ? ? InputStream in = new FileInputStream(srcFile);
? ? ? ? ? ? OutputStream out = new FileOutputStream(targetFile,true);
? ? ? ? ? ? byte[] bytes = new byte[5];
? ? ? ? ? ? int len = -1;
? ? ? ? ? ? while ((len = in.read(bytes)) != -1){
? ? ? ? ? ? ? ? out.write(bytes,0,len);
? ? ? ? ? ? }
? ? ? ? ? ? in.close();
? ? ? ? ? ? out.close();
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}
~~~
### 4)字節(jié)字符轉(zhuǎn)換流
轉(zhuǎn)換流,可以將一個(gè)字節(jié)流轉(zhuǎn)換為字符流,也可以將一個(gè)字符流轉(zhuǎn)換為字節(jié)流。
#### ①OutputStreamWriter
可以將輸出的字符流轉(zhuǎn)換為字節(jié)流的輸出形式
~~~java
package com.demo;
import java.io.*;
public class Test5 {
? ? public static void main(String[] args) {
? ? ? ? try {
? ? ? ? ? ? OutputStream out = new FileOutputStream(new File("F://ideaspace//test//src//com//demo//test.text"));
? ? ? ? ? ? writer(out); ?
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? public static void writer(OutputStream out){
? ? ? ? Writer writer = new OutputStreamWriter(out);
? ? ? ? try {
? ? ? ? ? ? writer.write("獨(dú)開(kāi)眾卉已凋時(shí),不畏風(fēng)霜向晚欺");
? ? ? ? ? ? writer.close();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}
~~~
#### ②InputStreamReader
將輸入的字節(jié)流轉(zhuǎn)換為字符流輸入形式
~~~java
package com.demo;
import java.io.*;
public class Test5 {
? ? public static void main(String[] args) {
// ? ? ? ?try {
// ? ? ? ? ? ?OutputStream out = new FileOutputStream(new File("F://ideaspace//test//src//com//demo//test.text"));
// ? ? ? ? ? ?writer(out);
// ? ? ? ?} catch (FileNotFoundException e) {
// ? ? ? ? ? ?e.printStackTrace();
// ? ? ? ?}
? ? ? ? try {
? ? ? ? ? ? InputStream in = new FileInputStream(new File("F://ideaspace//test//src//com//demo//test.text"));
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? reader(in);
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? public static void writer(OutputStream out){
? ? ? ? Writer writer = new OutputStreamWriter(out);
? ? ? ? try {
? ? ? ? ? ? writer.write("獨(dú)開(kāi)眾卉已凋時(shí),不畏風(fēng)霜向晚欺");
? ? ? ? ? ? writer.close();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? public static void reader(InputStream in) throws IOException {
? ? ? ? Reader reader = new InputStreamReader(in);
? ? ? ? char [] chars = new char[2];
? ? ? ? int len = -1;
? ? ? ? while ((len = reader.read(chars)) != -1){
? ? ? ? ? ? System.out.println(new String(chars,0,len));
? ? ? ? }
? ? ? ? reader.close();
? ? }
}
~~~
### 5)緩沖流
對(duì)文件或其它目標(biāo)頻繁的讀寫(xiě)操作,效率低,性能差。使用緩沖流的好處是,能夠更高效的讀寫(xiě)信息,原理是將數(shù)據(jù)先緩存起來(lái),然后一起寫(xiě)入或者讀取出來(lái)。
#### ①字節(jié)緩沖流
+ BufferedInputStream 為另一個(gè)輸入流添加一些功能,在創(chuàng)建BufferedInputStream時(shí),會(huì)創(chuàng)建一個(gè)內(nèi)部緩沖區(qū)數(shù)組,用于緩沖數(shù)據(jù)。
+ BufferedOutputStream 通過(guò)設(shè)置這種輸出流,應(yīng)用程序就可以將各個(gè)字節(jié)寫(xiě)入底層輸入流中,而不必針對(duì)每次字節(jié)寫(xiě)入調(diào)用底層系統(tǒng)。
~~~java
package com.demo;
import java.io.*;
public class Test7 {
? ? public static void main(String[] args) {
? ? ? ? File file = new File("F://ideaspace//test//src//com//demo//test1.text");
? ? ? ? try {
? ? ? ? ? ? OutputStream out = new FileOutputStream(file,true);
? ? ? ? ? ? BufferedOutputStream bos = new BufferedOutputStream(out);
? ? ? ? ? ? bos.write("你好".getBytes());
? ? ? ? ? ? bos.write("java".getBytes());
? ? ? ? ? ? bos.close();
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}
~~~
#### ②字符緩沖流
+ FileReader ?內(nèi)部使用InputStreamReader,解碼過(guò)程,byte->char,默認(rèn)緩存大小為8k。
+ BufferedReader 從字符輸入流中讀取文本,緩沖各個(gè)字符,從而實(shí)現(xiàn)字符、數(shù)組和行的高效讀取。
? 默認(rèn)緩存大小為8k,但可以手動(dòng)指定緩存的大小,把數(shù)據(jù)讀取到緩存中,減少每次轉(zhuǎn)換過(guò)程,效率更高
+ BufferedWriter ?將文本寫(xiě)入字符輸出流,緩沖各個(gè)字符,從而提供單個(gè)字符、數(shù)組和字符串的高效寫(xiě)入。
? 默認(rèn)緩存大小為8k,但可以手動(dòng)指定緩存的大小,把數(shù)據(jù)寫(xiě)入到緩存中,減少每次轉(zhuǎn)換過(guò)程,效率更高
### 6)打印流
+ PrintStream 字節(jié)打印流
? ~~~java
? package com.demo;
??
? import java.io.*;
??
? public class Test7 {
? ? ? public static void main(String[] args) {
? ? ? ? ? File file = new File("F://ideaspace//test//src//com//demo//test1.text");
? ? ? ? ? try {
? ? ? ? ? ? ? OutputStream out = new FileOutputStream(file,true);
? ? ? ? ? ? ? BufferedOutputStream bos = new BufferedOutputStream(out);
? ? ? ? ? ? ? PrintStream ps = new PrintStream(bos);
? ? ? ? ? ? ? ps.print("你好");
? ? ? ? ? ? ? ps.close();
? ? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? }
? ? ? }
? }
? ~~~
? + PrintWriter 字符打印流
? ? ~~~java
? ? package com.demo;
? ??
? ? import java.io.*;
? ??
? ? public class Test7 {
? ? ? ? public static void main(String[] args) {
? ? ? ? ? ? File file = new File("F://ideaspace//test//src//com//demo//test1.text");
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? Writer out = new FileWriter(file,true);
? ? ? ? ? ? ? ? BufferedWriter bw = new BufferedWriter(out);
? ? ? ? ? ? ? ? PrintWriter pw = new PrintWriter(bw);
? ? ? ? ? ? ? ? pw.print("你好");
? ? ? ? ? ? ? ? pw.close();
? ? ? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? ~~~
### 7)對(duì)象流與序列化
#### ①ObjectOutputStream?
將java對(duì)象的基本數(shù)據(jù)類型和圖形寫(xiě)入OutputStream
~~~java
package com.demo;
import java.io.*;
//如果一個(gè)類創(chuàng)建的對(duì)象,需要被序列化,那么該類必須實(shí)現(xiàn)Serializable接口
//Serializable是一個(gè)標(biāo)記接口,沒(méi)有任何定義,為了告訴JVM該對(duì)象可以被序列化
//什么時(shí)候?qū)ο笮枰恍蛄谢?#xff1f;
//1.把對(duì)象保存到文件中
//2.對(duì)象在網(wǎng)絡(luò)上傳輸
public class Test8 {
? ? public static void main(String[] args) {
? ? ? ? Dog dog = new Dog("旺財(cái)",2,"公");
? ? ? ? File file = new File("F://ideaspace//test//src//com//demo//test.text");
? ? ? ? OutputStream out = null;
? ? ? ? try {
? ? ? ? ? ? out = new FileOutputStream(file);
? ? ? ? ? ? ObjectOutputStream op = new ObjectOutputStream(out);
? ? ? ? ? ? op.writeObject(dog);
? ? ? ? ? ? op.close();
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? static class Dog implements Serializable{
? ? ? ? private String name;
? ? ? ? private int age;
? ? ? ? private String sex;
? ? ? ? public Dog() {
? ? ? ? }
? ? ? ? public Dog(String name, int age, String sex) {
? ? ? ? ? ? this.name = name;
? ? ? ? ? ? this.age = age;
? ? ? ? ? ? this.sex = sex;
? ? ? ? }
? ? }
}
~~~
#### ②ObjectInputStream?
對(duì)以前使用ObjectOutputStream寫(xiě)入的基本數(shù)據(jù)和對(duì)象進(jìn)行反序列化。
~~~java
package com.demo;
import java.io.*;
public class Test8 {
? ? public static void main(String[] args) {
? ? ? ? File file = new File("F://ideaspace//test//src//com//demo//test.text");
? ? ? ? try {
? ? ? ? ? ? InputStream in = new FileInputStream(file);
? ? ? ? ? ? ObjectInputStream ois = new ObjectInputStream(in);
? ? ? ? ? ? Dog dog = (Dog)ois.readObject();
? ? ? ? ? ? ois.close();
? ? ? ? ? ? System.out.println(dog.toString());
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (ClassNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? static class Dog implements Serializable{
? ? ? ? private String name;
? ? ? ? private int age;
? ? ? ? private String sex;
? ? ? ? public Dog() {
? ? ? ? }
? ? ? ? public Dog(String name, int age, String sex) {
? ? ? ? ? ? this.name = name;
? ? ? ? ? ? this.age = age;
? ? ? ? ? ? this.sex = sex;
? ? ? ? }
? ? ? ? @Override
? ? ? ? public String toString() {
? ? ? ? ? ? return "Dog{" +
? ? ? ? ? ? ? ? ? ? "name='" + name + '\'' +
? ? ? ? ? ? ? ? ? ? ", age=" + age +
? ? ? ? ? ? ? ? ? ? ", sex='" + sex + '\'' +
? ? ? ? ? ? ? ? ? ? '}';
? ? ? ? }
? ? }
}
~~~
### 8)數(shù)據(jù)流
#### ①DataOutputStream
數(shù)據(jù)輸出流允許應(yīng)用程序以適當(dāng)?shù)姆绞綄⒒緅ava數(shù)據(jù)類型寫(xiě)入輸出流中。然后,應(yīng)用程序可以使用數(shù)據(jù)輸入流將數(shù)據(jù)讀入。
~~~java
public static void out(){
? ? ? ? File file = new File("F://ideaspace//test//src//com//demo//test1.text");
? ? ? ? try {
? ? ? ? ? ? OutputStream out = new FileOutputStream(file);
? ? ? ? ? ? BufferedOutputStream bos = new BufferedOutputStream(out);
? ? ? ? ? ? DataOutputStream dos = new DataOutputStream(bos);
? ? ? ? ? ? dos.writeInt(10);
? ? ? ? ? ? dos.writeByte(1);
? ? ? ? ? ? dos.writeUTF("汪林");
? ? ? ? ? ? dos.close();
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
~~~
#### ②DataInputStream
數(shù)據(jù)輸入流允許應(yīng)用程序以與機(jī)器無(wú)關(guān)方式從底層輸入流中讀取java基本數(shù)據(jù)類型。應(yīng)用程序可以使用數(shù)據(jù)輸出流寫(xiě)入稍后由數(shù)據(jù)輸入流讀取的數(shù)據(jù)。DataInputStream對(duì)于多線程訪問(wèn)不一定是安全的。線程安全是可選的,它有此類方法的使用者負(fù)責(zé)。
~~~java
public static void in(){
? ? ? ? File file = new File("F://ideaspace//test//src//com//demo//test1.text");
? ? ? ? try {
? ? ? ? ? ? InputStream in = new FileInputStream(file);
? ? ? ? ? ? BufferedInputStream bis = new BufferedInputStream(in);
? ? ? ? ? ? DataInputStream dis = new DataInputStream(bis);
? ? ? ? ? ? int a = dis.readInt();
? ? ? ? ? ? byte b = dis.readByte();
? ? ? ? ? ? String name = dis.readUTF();
? ? ? ? ? ? dis.close();
? ? ? ? ? ? System.out.println(a+","+b+","+name);
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
~~~
### 9)文件分割合并示例
~~~java
package com.demo;
import java.io.*;
import java.util.Enumeration;
import java.util.Vector;
public class Test10 {
? ? /**
? ? ?* 文件的分割
? ? ?* targetFile 要分割的文件
? ? ?* cutSize 每個(gè)文件的大小
? ? ?*/
? ? public static void devision(File targetFile,long cutSize){
? ? ? ? if(targetFile == null)return;
? ? ? ? //計(jì)算總分割的文件數(shù)
? ? ? ? int num = targetFile.length()%cutSize == 0 ?
? ? ? ? ? ? ? ? (int)(targetFile.length()/cutSize) : (int)((targetFile.length()/cutSize)+1);
? ? ? ? //構(gòu)造一個(gè)文件輸入流
? ? ? ? try {
? ? ? ? ? ? BufferedInputStream bis = new BufferedInputStream(new FileInputStream(targetFile));
? ? ? ? ? ? BufferedOutputStream bos = null;
? ? ? ? ? ? byte [] bytes = null; //每次要讀取的字節(jié)數(shù)
? ? ? ? ? ? int len = -1;
? ? ? ? ? ? int count = 0; //每一個(gè)文件要讀取的次數(shù)
? ? ? ? ? ? for (int i = 0; i < num; i++) {
? ? ? ? ? ? ? ? bos = new BufferedOutputStream(new FileOutputStream("F://"+(i+1)+"-temp"+targetFile.getName()));
? ? ? ? ? ? ? ? if(cutSize <= 1024){
? ? ? ? ? ? ? ? ? ? bytes = new byte[(int)cutSize];
? ? ? ? ? ? ? ? ? ? count = 1;
? ? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? ? ? bytes = new byte[1024];
? ? ? ? ? ? ? ? ? ? if(cutSize%1024 == 0){
? ? ? ? ? ? ? ? ? ? ? ? count = (int)(cutSize/1024);
? ? ? ? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? ? ? ? ? count = (int)(cutSize/1024)+1;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? while (count>0 && (len=bis.read(bytes))!=-1){
? ? ? ? ? ? ? ? ? ? bos.write(bytes,0,len);
? ? ? ? ? ? ? ? ? ? bos.flush();
? ? ? ? ? ? ? ? ? ? count--;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? bos.close();
? ? ? ? ? ? }
? ? ? ? ? ? bis.close();
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? /**
? ? ?* 文件的合并
? ? ?*/
? ? public static void merge(Enumeration<InputStream> es){
? ? ? ? SequenceInputStream sis = new SequenceInputStream(es);
? ? ? ? try {
? ? ? ? ? ? BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("F://實(shí)驗(yàn)報(bào)告.doc"));
? ? ? ? ? ? byte[] bytes = new byte[1024];
? ? ? ? ? ? int len = -1;
? ? ? ? ? ? while ((len=sis.read(bytes))!=-1){
? ? ? ? ? ? ? ? bos.write(bytes,0,len);
? ? ? ? ? ? ? ? bos.flush();
? ? ? ? ? ? }
? ? ? ? ? ? bos.close();
? ? ? ? ? ? sis.close();
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? public static void main(String[] args) {
// ? ? ? ?File file = new File("E://大學(xué)課程//web實(shí)驗(yàn)//web實(shí)驗(yàn)報(bào)告.doc");
// ? ? ? ?devision(file,1024*512);
? ? ? ? try {
? ? ? ? ? ? InputStream in1 = new FileInputStream(new File("F://1-tempweb實(shí)驗(yàn)報(bào)告.doc"));
? ? ? ? ? ? InputStream in2 = new FileInputStream(new File("F://2-tempweb實(shí)驗(yàn)報(bào)告.doc"));
? ? ? ? ? ? InputStream in3 = new FileInputStream(new File("F://3-tempweb實(shí)驗(yàn)報(bào)告.doc"));
? ? ? ? ? ? Vector<InputStream> vector = new Vector<InputStream>();
? ? ? ? ? ? vector.add(in1);
? ? ? ? ? ? vector.add(in2);
? ? ? ? ? ? vector.add(in3);
? ? ? ? ? ? Enumeration<InputStream> es= vector.elements();
? ? ? ? ? ? merge(es);
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}
~~~
### 10)字符串流與管道流
#### ①字符串流
+ 定義:以一個(gè)字符串為數(shù)據(jù)源,來(lái)構(gòu)造一個(gè)字符流
+ 作用:在WEB開(kāi)發(fā)中,我們經(jīng)常要從服務(wù)器上獲取數(shù)據(jù),數(shù)據(jù)的返回格式通常是一個(gè)字符串(XML,JSON),我們需要把這個(gè)字符串構(gòu)造成一個(gè)字符流,然后再用第三方的數(shù)據(jù)解析器來(lái)解析數(shù)據(jù)。
? ~~~java
? package com.demo;
??
? import java.io.IOException;
? import java.io.StreamTokenizer;
? import java.io.StringReader;
??
? public class Test11 {
? ? ? public static void main(String[] args) {
? ? ? ? ? String info = "good good study day day up";
? ? ? ? ? StringReader sr = new StringReader(info);
? ? ? ? ? //流標(biāo)記器
? ? ? ? ? StreamTokenizer st = new StreamTokenizer(sr);
? ? ? ? ? int count = 0;
? ? ? ? ? while (st.ttype != StreamTokenizer.TT_EOF){
? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? if(st.nextToken() == StreamTokenizer.TT_WORD){
? ? ? ? ? ? ? ? ? ? ? count++;
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? ? ? System.out.println("count = "+count);
? ? ? }
? }
? ~~~
#### ②管道流
##?
總結(jié)
以上是生活随笔為你收集整理的Java面向对象基础呕心沥血三千字的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: DxO PhotoLab 3 for M
- 下一篇: DDPush 任意门消息推送 开源免