日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java面向对象基础呕心沥血三千字

發布時間:2023/12/14 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java面向对象基础呕心沥血三千字 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

# 一、初識Java

## 1.java關鍵字

public?? ?公共的、公開的?
class?? ?類
static?? ?靜態的
void?? ?空的?? ?
main?? ?main方法
String?? ?字符串
System ?系統

## 2.注意點

1)注意大括號、小括號、中括號成對出現
2)注意每一行代碼后有分號結束
3)注意所有符號都是英文符號
4)注意縮進(tab ?shift+tab)
5)公共類的類名要和源文件名同名

## 3.java注釋

### 1)單行注釋

//

### 2)多行注釋

/*
?....
*/

### 3)文檔注釋(javadoc注釋)

/**
?....
*/

## 4.常用快捷鍵

ctrl + s ?? ??? ??? ??? ?保存
ctrl + c?? ??? ??? ??? ?復制
ctrl + v?? ??? ??? ??? ?粘貼
ctrl + x?? ??? ??? ??? ?剪切
ctrl + z?? ??? ??? ??? ?撤銷上一步操作
ctrl + y?? ??? ??? ??? ?返回下一步操作
ctrl + a ?? ??? ??? ??? ?全選

ctrl + shift + 左右鍵 ?? ?選擇單詞
shit + home/end ?? ??? ?選擇一整行
alt + 上下鍵?? ??? ??? ?把光標所在行上下移動

alt + shift + r ?? ??? ?重命名
alt + insert?? ??? ??? ?新建
shift + 上下左右鍵 ?? ??? ?選擇內容
ctrl + / ?? ??? ??? ??? ?注釋
ctrl + shift + f?? ??? ?格式化代碼

# 二、變量、數據類型以及運算符

## 1.變量

變量類型:char、int、double、String

java中的8種基本類型:
byte char short int long float double boolean

變量命名規范:

可以由字母、數字、下劃線、$符號組成,開頭不能是數字
使用駱駝命名法命名(首字母小寫,后面每個單詞首字母大寫)

起有意的名字,見名知意

## 2.常量

final關鍵字用來修飾常量

final int num = 10;

num=100;//這一行報錯,因為常量不允許修改

## 3.運算符

### 1)賦值運算符

= 運算時把右側的值賦值給左側

### 2)算術運算符

+ -/ %

注意:
如果操作數都是整數
/ 是用來取商的
% 是用來取余數的

如果操作數中有一個是double(也可以都是)
則 / 可以計算出小數,需要用double來接收結果

### 3)比較運算符

==、>、<、>=、<=、!=

### 4)邏輯運算符

&& ?: 并且(與)
|| ?: 或者(或)
! ? : 非

優先級:非、與、或

/*
?* 討論關于java中幾種運算符之間的執行優先級
?* 1."()"運算優先級最高,一般可用于手動改變表達式中不同運算符的運算順序
?* 2.“!”,“++”,“--”稱為單目運算符(只對一個操作數進行運算稱為單目),優先級高
?* 3.對一些常用的運算符(雙目)之間:算術運算符 > 關系運算符 > 邏輯運算符
?* ? 3.1 算術運算符中: + - * / % ++ --
?* ? ? ? 除++,--之外:* / % 優先于 + - ,當有并列優先級時例如: 4 * 5 / 2,從左向右運算
?* ? 3.2 關系運算符: == ?!= ? > ? < ? >= ? <=
?* ? ? ? > ? < ? >= ? <= 只能用于數值類型的數據比較
?* ? ? ? > ? < ? >= ? <= 優先級高于 ?== ?!=
?* ? ? ? 當有并列優先級時例如: 5 > 3 == 2 < 4 ,從左向右運算
?* ?3.3 邏輯運算符: & ?&& ?| ?|| ?!
?* ? ? ?除!外:&& 優先于 ||
?* ? ? ?邏輯與(&) 同 短路與(&&) 相比:不論第一個操作數是否為false,都會運算第二個操作數,而短路與不會
?* ? ? ?邏輯(|) ?同 ?短路或(||) 相比: 不論第一個操作室是否為true,都會運算第二個操作數,而短路或不會
?* 4. ?“=”,"?:","!","++","--"這5個符合在運算時從右向左。
?* 總結:
?* ? ? ?"!","++","--"(同時出現在一個表達式中時,從右向左)
?* ? ? ?優先于
?* ? ? ?"*","/","%" (從左向右)
?* ? ? ?優先于
?* ? ? ?"+","-" (從左向右)
?* ? ? ?優先于
?* ? ? ?">","<",">=","<="(從左向右)
?* ? ? ?優先于
?* ? ? ?"&","&&"
?* ? ? ?優先于
?* ? ? ?"|","||"
?* ? ? ?優先于
?* ? ? ?"?:"
?* ? ? ?以上優先級為java表達式運算時的默認執行順序,任何一個運算符在使用“()”時都將提升為最高,
?* ? ? ? 有多個()并列出現時,從左往右
?* ? ? ? 有多個()嵌套出現時,從內向外
?*/

## 4.類型轉換

### 1)自動類型轉換

int a = 5;
double b = 2.5;
double c = a + b; //表達式中如果有double類型,則整體運算結果提升為double類型

int a = 5;
double b = a; ?? ? ?//自動提升,int可以直接賦值給double

### 2)強制類型轉換

double a = 123.567;
int b = a; ?? ??? ?//這樣會報錯,double類型不能直接賦值給int類型,數據寬度問題
int b = (int)a; // 這樣就是強轉了,b的結果是123,小數部分舍棄

## 5.其他

### 1)從控制臺輸入

先導包
import java.util.Scanner;

再聲明Scanner對象
Scanner input = new Scanner(System.in)

再使用相應的方法從控制臺獲取用戶輸入的數據
String name = input.next();
int age = input.nextInt();
double score = input.nextDouble();

### 2)++的問題

int a = 5;
a++; ?//等價于 a = a + 1

# 三、流程控制—選擇結構和循環結構

## 1.流程圖

菱形:條件判斷
矩形:運算
平行四邊形:輸入、輸出
圓角矩形:開始、結束

![image-20211202161501565](images/image-20211202161501565.png)

## 2.if語句

if(條件){
? //代碼塊
}?? ?

if(條件){
? //代碼塊1
}else{
? //代碼塊2
}

多重if語句 :

if(條件1){
? //代碼塊1
}else if(條件2){
? //代碼塊1
}else{
? //...
}

嵌套if語句:

if(條件1){
? //...
? if(條件2){
? ? //...
? }
? //...
}else{
? //....
}

## 3.字符串的判斷相等

equals() 字符串等值比較
equalsIgnoreCase() 忽略字母大小寫進行比較

## 4.switch

注意點:
1)switch的變量類型允許的:
? int、char、byte、short、String(jdk1.8以后)
1)case后的常量不能重復
2)case的順序可以調換
3)break如果省略,會出現貫穿的情況
4)default一般放在最后,其中的break可以省略
? 從語法上來看default也可以省略

/*
?* switch分支結構的特點:
?* 1、只能用于表達式運算結果和case之后的常量值之間的等值判斷
?* 2、表達式只能是:int,short,byte,char,String,枚舉這些類型
?* 3、在每個case后的break可以省略,
?* ? 若省略則執行該case分支代碼后將“貫穿”執行下一個case的代碼塊,
?* ? 這種“貫穿”直到遇到break或者switch的”}“為止
?* 4、多個case后的常量值不能相同
?* 5、如果default的位置不在最后,表達式判斷的順序不變,
?* ? ?仍舊是先判斷所有case,在不滿足任何case后才執行default分支
?* 6、當有等值判斷的多分支需求時,超過3個以上分支使用switch效率比多重if要高
?*/

![image-20211207143658364](images/image-20211207143658364.png)

# 四、數組

## 1.數組的定義

存儲固定大小的同類型元素

## 2.數組的創建

~~~java
int[] nums;//聲明數組
nums = new int[5];//創建數組
int[] nums1 = new int[5];//聲明并創建數組
int nums2 = {1,2,3,4,,5};//創建的同時并給數組賦初始值
int nums3 = new int{1,2,3,4,5};//創建的同時并給數組賦初始值
~~~

## 3.數組的訪問

通過下標訪問

# 五、面向對象和封裝

## 1.類和對象的關系

類是對象的抽象,對象是類的具體表現

## 2.類的成員:

+ 屬性:描述類的靜態特征
? + 類變量:類加載時就會分配空間,通過類名調用,不提倡通過對象調用
? + 成員變量:調用構造函數時才會分配空間,只能通過對象調用。
+ 方法:描述類的動態行為
+ 代碼塊:
? + 靜態代碼塊:加載類是執行的代碼塊
? + 代碼塊:定義對象是執行的代碼塊

## 3.構造方法

+ 初始化類的屬性
+ 方法名與類名相同

## 4.對象的創建

~~~java
Car car = new Car(); //new 關鍵字創建空間,構造方法用于初始化屬性
~~~

# 六、繼承和多態

## 1.繼承的基本概念

繼承是從已有的類創建新類的過程。

+ 繼承是面向對象的三大特征之一
+ 被繼承的類被稱為父類(超類),繼承父類的類叫做子類(派生類)
+ 繼承是指一個對象直接使用另一個對象的屬性和方法
+ 通過繼承可以實現代碼重用

## 2.繼承的限制

+ java只能實現單繼承,也就是一個類只能又一個父類。
+ 允許多層繼承,即:一個子類可以有一個父類,一個父類還可以有其他的父類。
+ 繼承只能繼承非私有的屬性和方法。
+ 構造方法不能被繼承

![image-20211223163501262](images/image-20211223163501262.png)

## 3.子類的實例化過程

在子類經行實例化操作的時候,首先會讓其父類進行初始化操作,之后子類再自己進行實例化操作。

### 1)子類的實例化過程:

子類實例化時會先調用父類的構造方法,如果父類中沒有默認的構造方法,在子類的構造方法中必須顯示的調用父類的構造方法?? ?。

### 2)結論:

構造方法只是用于初始化類中的字段以及執行一些初始化代碼,**調用構造方法并不代表會產生對象**。

## 4.方法重寫

### 1)方法重寫:

在java中,子類可以繼承父類中的方法,而不需要重新編寫相同的方法。但有時子類不想原封不動地繼承父類的方法,而是想做一定的修改,這就需要采用方法的重寫。方法重寫又稱方法覆蓋。在子類和父類中,重寫方法后,在調用時,以創建的對象類型為準,會調用誰的方法。

### 2)方法重寫的一些特性

+ 發生在子父類中,方法重寫的兩個方法的返回值、方法名、參數列表必須完全一致。
+ 子類拋出的異常不能超過父類相應方法拋出的異常。
+ 子類方法的訪問級別不能低于父類相應方法的訪問級別。
+ 父類中的方法若使用private、static、final任意修飾符修飾,不能被子類重寫。

![image-20211224100007100](images/image-20211224100007100.png)

## 5.super關鍵字

+ 使用super調用父類中的屬性,可以從父類實例中獲得信息。

+ 使用super調用父類中的方法,可以委托父類對象幫助完成某件事情。

+ 使用super調用父類的構造方法(super(實參)形式),必須在子類構造方法中的第一條語句,調用父類中相應的構造方法,若不顯示的寫出來,默認調用父類無參的構造方法。

## 6.final關鍵字

+ 使用final關鍵字聲明一個變量:修飾屬性或者修飾局部變量,也稱為常量。
+ 使用final關鍵字聲明一個方法:該方法為最終方法,只能被子類繼承,不能被子類改寫。
+ 使用final關鍵字聲明一個類:該類就轉變成為最終類,無法被繼承。
+ 在方法參數中使用final關鍵字:在方法內部不能修改參數的值(在內部中詳解)。

## 7.多態性

+ 方法的重寫與重載就是方法的多態性表現
+ 多個子類就是父類中的多種形態
+ 父類引用可以指向子類對象,自動轉換
+ 子類對象指向父類引用需要強制轉換(類型不對會報異常)
+ 在實際開發中盡量使用父類引用(更利于擴展)

## 8.instanceof關鍵字

是用于檢查對象是否為指定的類型,通常在把父類引用強制轉換為子類引用時要使用,以避免發生類型轉換異常(ClassCastException)。

# 七、抽象類、接口和異常

## 1.抽象類的基本概念

+ 很多具有相同特征和行為的對象可以抽象為一個類,很多具有相同特征和行為的類可以抽象為一個抽象類
+ 使用abstract關鍵字聲明的類為抽象類
+ 抽象類不能被實例化

## 2.抽象方法的基本概念

+ 在Java中,當一個類的方法被abstract關鍵字修飾時,該方法稱為抽象方法。抽象方法所在的類必須定義為抽象類。
+ 抽象方法沒有方法體。

## 2.接口

### 1)接口的使用規則

+ 定義一個接口使用interface關鍵字
+ 在一個接口中,只能定義常量、抽象方法,JDK1.8后可以定義默認的實現方法
+ 接口可以繼承多個接口:extends xxx,xxx
+ 一個具體類實現接口使用implements關鍵字
+ 一個類可以實現多個接口
+ 抽象類實現接口可以不實現接口的方法
+ 在接口中定義的方法沒有聲明訪問修飾符,默認為public
+ 接口不能有構造方法
+ 接口不能被實例化

### 2)面向對象設計原則

+ 對修改關閉,對擴展開放
+ 面向接口編程

## 3.oo原則總結

+ 開閉原則:一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。
+ 合成/聚合復用原則:新對象的某些功能在已創建好的對象里實現,那么盡量用已有對象提供的功能,使之成為新對象的一部分,而不要再重新創建。
+ 依賴倒置原則:高層模塊不依賴底層模塊,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。
+ 接口隔離原則:客戶端不應該依賴它不需要的接口,一個類對另一個類的依賴應該建立在最小的接口之上。
+ 迪米特法則:一個對象應該對其它對象保持最少的了解。
+ 里氏替換原則:所有引用基類的地方必須能夠透明地使用其子類對象。
+ 單一職責原則:不要存在多于一個導致類變更地原因,即一個類知負責一項原則。

## 4.抽象類與接口的異同點

相同點:

+ 不能實例化對象,只能通過子類(實現類)對象指向指向自己的引用
+ 都可以有抽象方法、屬性
+ 都屬于父級元素

不同點:

+ 接口的方法只能是抽象方法和靜態方法,抽象類可以有抽象方法,也可以沒有,其他類型的方法也都可以有
+ 接口中的屬性只能是公有靜態屬性(public static final),抽象類沒有限制
+ 本質不同,一個是類,一個是接口

## 5.異常

### 1.異常的定義:

異常是指在程序的運行過程中所發生的不正常的事件,它會中斷正在運行的程序。

### 2.異常處理的五個關鍵字:

try、catch、finally、throws、throw

finally代碼塊只有在catch塊中有System.exit()時才不會執行,其他任何情況都會執行。

![image-20211230101038341](images/image-20211230101038341.png)

# 八、Object類和內部類

## 1.Object類

每個類都是用Object類作為超類。所有對象(包括數組)都實現這個類的方法。

## 2.內部類

### 1)成員內部類

~~~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("我是內部類");
? ? ? ? }
? ? }
}
~~~

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖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("我是成員內部類");
? ? ? ? }
? ? }
}
~~~

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖8.2

上述兩份代碼皆為內部類方法的調用,建議使用第二種。第二種封裝了內部類,向外提供了使用內部類的接口(方法)。

### 2)方法內部類

+ 方法內部類只能在定義該內部類的方法內進行實例化,不可以在方法外進行實例化。
+ 方法內部類對象不能使用該內部類所在方法的非final局部變量(jdk1.8之后一旦使用了沒有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("我是成員內部類");
? ? ? ? }
? ? }
? ? public void method(){
? ? ? ? class C{
? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? System.out.println("我是方法內部類");
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? C c = new C();
? ? ? ? c.say();
? ? }
}
~~~

### 3)靜態內部類

靜態的含義是該內部類可以像其它靜態成員一樣,沒有外部類對象時,也能夠訪問它。靜態內部類僅能訪問外部類的靜態成員和方法。

~~~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("我是成員內部類");
? ? ? ? }
? ? }
? ? public void method(){
? ? ? ? class C{
? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? System.out.println("我是方法內部類");
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? C c = new C();
? ? ? ? c.say();
? ? }
? ? static class D{
? ? ? ? public void say(){
? ? ? ? ? ? System.out.println("我是靜態內部類");
? ? ? ? }
? ? }
}
~~~

### 4)匿名內部類

+ 繼承式匿名內部類

? ~~~java
? public class Demo5 {
? ? ? public static void main(String[] args) {
? ? ? ? ? Cat cat = new Cat(){
? ? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? ? System.out.println("我是繼承式匿名內部類");
? ? ? ? ? ? ? }
? ? ? ? ? };
? ? ? ? ? cat.say();
? ? ? }
? }
? abstract class Cat{
? ? ? abstract public void say();
? }
? ~~~

??

+ 接口式匿名內部類

? ~~~java
? public class Demo5 {
? ? ? public static void main(String[] args) {
? ? ? ? ? Cat cat = new Cat(){
? ? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? ? System.out.println("我是繼承式匿名內部類");
? ? ? ? ? ? ? }
? ? ? ? ? };
? ? ? ? ? cat.say();
??
? ? ? ? ? Icat cat1 = new Icat() {
? ? ? ? ? ? ? public void say(){
? ? ? ? ? ? ? ? ? System.out.println("我是接口式匿名內部類");
? ? ? ? ? ? ? }
? ? ? ? ? };
? ? ? ? ? cat1.say();
? ? ? }
? }
? abstract class Cat{
? ? ? abstract public void say();
? }
? interface Icat{
? ? ? void say();
? }
? ~~~

??

+ 參數式匿名內部類

? ~~~java
? public class Demo5 {
? ? ? public static void main(String[] args) {
? ? ? ? ? Demo demo = new Demo();
? ? ? ? ? demo.say(new Icat() {
? ? ? ? ? public void say(){
? ? ? ? ? ? ? System.out.println("我是參數式匿名內部類");
? ? ? ? ? }
? ? ? ? ? });
? ? ? }
? }
??
? interface Icat {
? ? ? void say();
? }
??
? class Demo {
? ? ? public void say(Icat icat) {
? ? ? ? ? icat.say();
? ? ? }
? }
??
? ~~~

??

### 5)使用匿名內部類的原則:

? + 不能有構造方法,只能由一個實例
? + 不能定義任何靜態成員、靜態方法(沒有類名)
? + 一定是跟在new的后面,用其隱含實現一個接口或繼承一個類
? + 匿名內部類為局部的,所以局部內部類的所有限制都對其生效

### 6)內部類的作用:

? 每個內部類都能獨立地繼承自一個(接口地)實現,所以無論外部類是否繼承了某個(接口的)實現,對于內部類都沒有影響。如果沒有內部類提供的可以繼承多個具體的或抽象的類的能力,一些設計與編程問題就很難解決。從這個角度看,內部類使得多重繼承的解決方案變得完整。接口解決了部分問題,而內部類有效地實現了“多重繼承”。

# 九、數據結構之鏈表

? ~~~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; //根節點
? ? ? 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();
? ? ? ? ? }
? ? ? }
??
? ? ? //查找是否存在節點
? ? ? 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;
? ? ? ? ? }
??
? ? ? ? ? //添加節點
? ? ? ? ? public void addNode(int data) {
? ? ? ? ? ? ? if (this.next == null) {
? ? ? ? ? ? ? ? ? this.next = new Node(data);
? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? this.next.addNode(data);
? ? ? ? ? ? ? }
? ? ? ? ? }
??
? ? ? ? ? //刪除節點
? ? ? ? ? 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);
? ? ? ? ? ? ? }
? ? ? ? ? }
??
? ? ? ? ? //打印所有節點
? ? ? ? ? public void printNode() {
? ? ? ? ? ? ? if (this.next != null) {
? ? ? ? ? ? ? ? ? System.out.print(this.next.getData() + " ");
? ? ? ? ? ? ? ? ? this.next.printNode();
? ? ? ? ? ? ? }
? ? ? ? ? }
??
? ? ? ? ? //查找節點是否存在
? ? ? ? ? public boolean findNode(int data) {
? ? ? ? ? ? ? if (this.next != null) {
? ? ? ? ? ? ? ? ? if (this.next.getData() == data) {
? ? ? ? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? return this.next.findNode(data);
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? }
? ? ? ? ? ? ? return false;
? ? ? ? ? }
??
? ? ? ? ? //修改節點
? ? ? ? ? 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);
? ? ? ? ? ? ? }
? ? ? ? ? }
??
? ? ? ? ? //插入節點
? ? ? ? ? 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);
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? ? }
? }
??
? ~~~

??

# ? 十、基本數據類型包裝類

## 1.裝箱及拆箱操作

將一個基本數據類型轉換為包裝類,那么這樣的操作稱為裝箱操作。將一個包裝類轉換為基本數據類型,這樣的操作稱為拆箱操作。

~~~java
public class Demo1 {
? ? //將基本數據類型轉換為包裝類,稱為自動裝箱
? ? Integer i1 = new Integer(10);
? ? //將包裝類轉換為基本數據類型,稱為自動拆箱
? ? int i2 = i1.intValue();

? ? Integer i3 = 10; //建議方式
? ? Integer i4 = new Integer("123");

? ? //把數值字符串轉換為int類型
? ? String num1 = "12";
? ? int i5 = Integer.parseInt(num1);

? ? Integer i6 = Integer.valueOf(num1);
? ? int i7 = Integer.valueOf(num1); //自動拆箱
}
~~~

# 十一、常用類庫

## 1.String類

+ String類可以表示一個字符串
+ **String類實際上是用字符數組存儲的**
+ 使用final修飾,不能被繼承

### 1)String類的兩種賦值方式:

~~~java
//直接賦值
String name1 = "小白";
//通過關鍵字new調用String的構造方法賦值
//下面的代碼會創建兩個對象(如果常量池中沒有小黑,就會在常量池中創建這個對象,然后通過new再在堆中創建一個小黑對象
String name2 = new ?String("小黑");
~~~

### 2)直接賦值字符串連接的4種情況:

考慮編譯期和運行期,如果代碼在編譯期就可以被確定,那么就使用已有的對象,否則會在運行其創建新的對象。

~~~java
public class Demo1 {
? ? public static void main(String[] args) {
? ? ? ? //結果為false
? ? ? ? String a = "a"; ?
? ? ? ? String a1 = a+1; ?//在編譯期a1看到的a是變量所以a1不能確定
? ? ? ? String a2 = "a1";
? ? ? ? System.out.println(a1 == a2);
? ? ? ??
? ? ? ? //結果為true
? ? ? ? final String b = "b"; ?
? ? ? ? String b1 = b+1; ?//b被申明為常量,b1在編譯期可以確定
? ? ? ? String b2 = "b1";
? ? ? ? System.out.println(b1 == b2);
? ? ? ??
? ? ? ? //結果為false
? ? ? ? String c = getC(); ?
? ? ? ? String c1 = getC() + 1; ?//方法只有在運行期才被調用,所以c1的值也無法確定,要在運行期在堆中用new創建
? ? ? ? String c2 = "c2";
? ? ? ??
? ? ? ? //結果為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) ?根據下標找到指定的字符
+ 普通方法 public char [] toCharArray() 以字符數組的形式返回字符串的全部內容
+ 構造方法 public String (char [] value) ?將全部的字符數組變為字符串
+ 構造方法 public String (char [],int offset,int count) 將指定范圍內的字符數組變為字符串

#### ②String類字節與字符串操作方法

+ 普通方法 public byte [] getBytes() 將字符串變為字節數組
+ 構造方法 public String(byte [] bytes) 將字節數組變為字符串
+ 構造方法 public String(byte [] bytes,int offset,int count) 將指定范圍內的字節數組變為字符串
+ 構造方法 public String(byte [] bytes,String charsetName) 通過使用指定的charset解碼指定的byte數組,構造一個新的String對象

將字節數組轉換為字符數組:

~~~java
? ? ? ? String s = "小黑";
? ? ? ? System.out.println(s.toCharArray());
? ? ? ? System.out.println(Arrays.toString(s.getBytes()));
~~~

#### ③String類判斷是否以指定內容開頭或結尾

+ 普通方法 public boolean startWith(String prefix) 從第一個位置開始判斷是否以指定的內容開頭
+ 普通方法 public boolean startWith(String prefix,int toffset) 從指定的位置開始判斷是否以指定的內容開頭
+ 普通方法 public boolean endWith(String suffix) ?判斷是否以指定的內容結尾

#### ④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) 替換第一個滿足條件的字符串

#### ⑤String類字符串截取操作

+ 普通方法 public String subString(int beginIndex) 從指定位置開始一直截取到末尾
+ 普通方法 public String subString(int beginIndex,int endIndex) 截取指定范圍內的字符串

#### ⑥String類字符串拆分操作

+ 普通方法 public [] String spit(String regex) ?按照指定的字符串拆分
+ 普通方法 public [] String ?spit(String regex,int limit) ?拆分字符串,并指定拆分的個數

#### ⑦String類字符串查找操作

+ 普通方法 public boolean contains(String s) ?返回一個字符串是否存在
+ 普通方法 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() ?判斷字符串的內容是否為空,**不是null**
+ 普通方法 public int length() 取得字符串的長度
+ 普通方法 public String toLowerCase() ?轉小寫
+ 普通方法 public String toUpperCase() 轉大寫
+ 普通方法 public String trim() 去掉開頭和結尾的空格,中間的空個不去
+ 普通方法 public String concat(String str) 字符串連接操作

## 2.StringBuffer類

### 1)StringBuffer介紹

使用String連接字符串,代碼性能會非常低,因為String的內容不可變。StringBuffer使用動態數組的方式擴充數組,使得StringBuffer對象的內容是可變的,有效地解決了連接字符串時代碼性能低的問題。

### 2)StringBuffer常用操作方法

+ 構造方法 public StringBuffer() ?構造一個空的StringBuffer對象
+ 構造方法 public StringBuffer(String str) ?將指定的String變為StringBuffer的內容
+ 構造方法 public StringBuffer(CharSequence ?seq) ?接收CharSequence接口的實例
+ 普通方法 public StringBuffer append(數據類型 b) ? 提供了很多append()方法,用于進行字符串連接
+ 普通方法 public StringBuffer delete(int start,int end) ? 刪除指定位置的內容
+ 普通方法 public int indexOf(String str) ? 字符串的查詢功能
+ 普通方法 public StringBuffer insert(int offset,數據類型 b) ? 在指定位置增加一個內容
+ 普通方法 public StringBuffer replace(int start,int end,String str) ?將指定范圍內的內容替換成其它內容
+ 普通方法 public String substring(int start,int end) ?截取指定范圍內的字符串
+ 普通方法 public String substring(int start) ?字符串截取
+ 普通方法 public StringBuffer reverse() 字符串反轉

## 3.StringBuilder類

StringBuilder介紹

一個可變的字符序列。此類提供了與StringBuffer兼容的API,但不保證同步。該類被設計用作StringBuffer的一個簡易替換,用在字符緩沖區被單個線程使用的時候(這種情況很普遍)。如果可能,建議先采用該類,因為在大多數的實現中,它比StringBuffer要快。

## 4.Math與Random類

### 1)Math類的常用方法:

+ abs(double a) ?返回double值的絕對值
+ random() ? 返回帶正號的double值,該值大于等于0.0且小于1.0
+ round(double a) ?返回最接近參數并且等于某一整數的double值
+ sqrt(double) ? 返回正確舍入的double值的平方根

### 2)Random類的常用方法

此類的實例用于生成偽隨機數流

+ nextLong() ? 返回下一個偽隨機數的long值
+ nextBoolean() ?返回下一個偽隨機數的boolean值、
+ nextDouble() ? 返回下一個偽隨機數,在0.0和1.0之間的double值
+ nextFloat() ? 返回下一個偽隨機數,在0.0和1.0之間的float值
+ nextInt() ?返回下一個偽隨機數的int值
+ nextInt(int n) ? 返回下一個偽隨機數,在0(包括)和指定值分布的int值

## 5.日期操作類

### 1)Date類

類Date表示特定的瞬間,精確到毫秒,也就是程序運行時的當前時間。

~~~java
Date date = new Date(); ?//實例化Date對象,表示當前時間
~~~

### 2)Calendar類(抽象類)

日歷類,使用此類可以將時間精確到毫秒顯示

~~~java
//兩種實例化方式
Calendar c1 = Calendar.getInstance();
Calendar c2 = new GregorianCalendar();?
int year = c1.get(Calendar.YEAR) ?//獲取當前時間的年份
int month = c1.get(Calendar.MONTH) //獲取當前時間的月份
int day = c1.get(Calendar.DAY_OF_MONTH) //獲取當前時間的天數
int hour = c1.get(Calendar.HOUR_OF_DAY) ?//獲取當前時間的小時數
int minute = c1.get(Calendar.MINUTE) ?//獲取當前時間的分鐘數
int second = c1.get(Calendar.SECOND) ? //獲取當前時間的秒數
int millisecond = c1.get(Calendar.MILLISECOND) ?//獲取當前時間的毫秒數
~~~

### 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接口

此接口強行對實現它的每個類的對象進行整體排序。這種排序被稱為類的自然排序,類的compareTo方法被稱為他的自然比較方法。

### 2)Comparator接口

Comparable接口是要求自定義類去實現,按照oo原則,對修改關閉,對擴展開放。Comparator接口強行對某個對象collection進行整體排序的比較。

## 7.Cloneable(對象的克隆)

將一個對象復制一份,稱為對象的克隆技術。

在Object類中存在一個clone()方法:protected Object clone() throws CloneNotSupportedException?

如果某個類的對象想要被克隆,則對象所在的類必須實現Cloneable接口。此接口沒有定義任何方法,是一個標記接口。

~~~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代表系統,系統級的很多屬性和控制方法都放置在該類的內部。該類位于java.lang包。

+ **成員變量**:System類內部包含in、out和err三個成員變量,分別代表標準輸入流(鍵盤輸入),標準輸出流(顯示器)和標準錯誤輸出流。

+ **成員方法**:

? public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length) ?該方法的作用是數組拷貝,也就是將一個數組中的內容復制到另一個數組中的指定位置,由于該方法時native方法,所以性能上比使用循環高效。

? public static long currentTimeMillis() ?該方法的作用時返回計算機的當前時間,時間的表達格式和GMT(格林威治時間)所差的的毫秒數。

? public static void exit(int status) ?該方法的作用是退出程序。其中status的值為0代表正常退出,非零代表異常退出

? public static void gc() ? 該方法的作用時請求系統進行垃圾回收。至于系統是否回收垃圾,則取決于系統中垃圾回收算法的實現以及系統執行時的情況。

? public static String getProperty(String key) ?該方法的作用是獲得系統中屬性名為key的屬性對應的值。

? ~~~java
? int [] num1 = {1,2,3,4};
? int [] num2 = new int[5];
? //參數:源數組,源數組的起始位置,目標數組,目標數組的起始位置,復制的長度
? System.arraycopy(num1,0,num2,1,num1.length);
? System.out.println(Arrays.toString(num2));
? System.out.println(System.currentTimeMillis());
? ~~~

### 2)Runtime類

每個應用程序都有一個Runtime的實例,使應用程序能夠與其運行的環境連接。

~~~java
//獲取java運行時相關的運行時對象
? ? ? ? Runtime rt = Runtime.getRuntime();
? ? ? ? System.out.println("處理器數量:"+rt.availableProcessors()+"個");
? ? ? ? System.out.println("Jvm總內存數:"+rt.totalMemory()+"byte");
? ? ? ? System.out.println("Jvm空閑內存數:"+rt.freeMemory()+"byte");
? ? ? ? System.out.println("Jvm可用最大內存數:"+rt.maxMemory()+"byte");

? ? ? ? //在單獨的進程中執行指定的字符串命令
? ? ? ? rt.exec("notepad");
~~~

## 9.數字處理工具類

### 1)BigInteger

可以讓超過integer范圍內的數據進行運算

~~~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); ?//除和取余,返回一個數組
~~~

### 2)BigDecimal

由于在運算的時候,float和double很容易丟失精度,為了能精確的表示,計算浮點數,java提供了BigDecimal,不可變的、任意精度的有符號十進制數。

~~~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); ?//除,可能會有除不盡的情況發生,這時會報異常 ,解決辦法是:b3.scale()-b4.scale()
b3.remainder(b4); ?//取余
b3.divideAndRemainder(b4); ?//除和取余,返回一個數組
~~~

### 3)DecimalFormat

java提供DecimalFormat類,幫你快速用最快的速度將數字格式化為你需要的樣子。

~~~java
double pi = 3.1415927;
//取一位整數,結果是3
System.out.println(new DecimalFormat("0").format(pi));
//取一位整數和兩位小數,結果是3.14
System.out.println(new DecimalFormat("0.00").format(pi));
//取兩位整數和三位小數,整數不足部分以0填補,結果是:03.142
System.out.println(new DecimalFormat("00.000").format(pi));
//取所有整數部分,結果為:3
System.out.println(new DecimalFormat("#").format(pi));
//以百分比方式計數,并取兩位小數,結果為: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");
? ? ? ? ? ? //通過MD5計算摘要
? ? ? ? ? ? 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.數據結構之二叉樹實現

### 1)簡介

樹是一種重要的非線性數據結構,直觀地看,它是數據元素(在樹中稱為節點)按分支關系組織起來的結構。二叉樹是每個節點最多有兩個子樹的有序樹。通常子樹被稱為”左子樹“和”右子樹“。

### 2)二叉樹算法的排序規則

+ 選擇第一個元素作為根節點
+ 之后如果元素大于根節點放在右子樹,小于根節點則放在左子樹
+ 最后按照中序遍歷的方式進行輸出

~~~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類可以實現文件的創建、刪除、重命名、得到路徑、創建時間等等,是唯一與文件本身有關的操作類。

### 2)File類的操作方法

+ public static final String separator ? 表示路徑分隔符
+ public File(String pathname) ? 構造File類實例,要傳入路徑
+ public boolean creatNewFile() ?創建新文件
+ public boolean delete() ?刪除文件,文件夾中有文件時刪除不了,得清空文件夾才能刪除
+ public boolean isFile() ? 判斷給定的路徑是否是文件
+ public String [] list() ?列出文件夾中文件,字符串數組的形式
+ public File [] listFiles() 列出文件夾中的所有文件,返回文件數組
+ public boolean mkdir() ?創建新的文件夾
+ public boolean reanmeTo(File dest) ?為文件重命名并且移動到指定的路徑處,等同于剪切并復制
+ 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("相對路徑="+f3.getPath());
? ? ? ? ? ? System.out.println("絕對路徑= "+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("文件最后修改時間="+dateFormat.format(date));
? ? ? ? ? ? System.out.println("------------------------------------");
? ? ? ? }
? ? ? ? //返回指定后綴名的文件數組
? ? ? ? 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流是輸入輸出流。流是一組有序的,有起點和終點的字節集合,是對數據傳輸的總稱或抽象。即數據在兩設備間的傳輸稱為流。流的本質是數據傳輸,根據數據傳輸特性將流抽象為各種類,方便更直觀地進行數據操作。
+ IO流地分類:根據處理數據類型地不同分為:字符流和字節流;根據流向不同分為:輸出流和輸入流。

### 1)字節輸入輸出流

#### ①字節輸出流

OutputStream類定義

public abstract class OutputStream extends Object implements Closeable,Flushable

此抽象類是表示輸出字節流的所有類的超類。輸出流接受輸出字節并將這些字節發送到InputStream類某個接收器要向文件中輸出,使用FileOutputStream類

#### ②字節輸入流

public abstract class IutputStream extends Object implements Closeable

此抽象類是表示字節輸入流的所有類的超類

FileInputStream從文件系統中的某個文件獲得輸入字節

~~~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 = "獨開眾卉已凋謝,不畏風霜向晚欺\r\n";
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? out.write(info.getBytes());
? ? ? ? ? ? ? ? out.close();
? ? ? ? ? ? ? ? System.out.println("成功寫入!");
? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? }
? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
? ? public static void main(String[] args) {
? ? ? ? //out();
? ? ? ?in();
? ? }
}
~~~

### 2)字符輸入輸出流

#### ①Writer

寫入字符流抽象類。子類必須實現的方法有write(char[],int,int)、flush()、close()。但是,多數子類將重寫此處定義的一些方法,以提供更高的效率和/或其它功能。 ?與OutputStream一樣,對文件的操作使用:FileWriter完成。

#### ②Reader

用于讀取字符的抽象類。子類必須實現的方法有read(char[],int,int)和close()。但是,多數子類將重寫此處定義的一些方法,以提供更高的效率和/或其它功能。與InputStream一樣,對文件的操作使用: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("掃碼領紅包\r\n");
? ? ? ? ? ? out.close();
? ? ? ? ? ? System.out.println("寫入成功");
? ? ? ? } 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)文件復制示例

~~~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)字節字符轉換流

轉換流,可以將一個字節流轉換為字符流,也可以將一個字符流轉換為字節流。

#### ①OutputStreamWriter

可以將輸出的字符流轉換為字節流的輸出形式

~~~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("獨開眾卉已凋時,不畏風霜向晚欺");
? ? ? ? ? ? writer.close();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}
~~~

#### ②InputStreamReader

將輸入的字節流轉換為字符流輸入形式

~~~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("獨開眾卉已凋時,不畏風霜向晚欺");
? ? ? ? ? ? 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)緩沖流

對文件或其它目標頻繁的讀寫操作,效率低,性能差。使用緩沖流的好處是,能夠更高效的讀寫信息,原理是將數據先緩存起來,然后一起寫入或者讀取出來。

#### ①字節緩沖流

+ BufferedInputStream 為另一個輸入流添加一些功能,在創建BufferedInputStream時,會創建一個內部緩沖區數組,用于緩沖數據。
+ BufferedOutputStream 通過設置這種輸出流,應用程序就可以將各個字節寫入底層輸入流中,而不必針對每次字節寫入調用底層系統。

~~~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 ?內部使用InputStreamReader,解碼過程,byte->char,默認緩存大小為8k。

+ BufferedReader 從字符輸入流中讀取文本,緩沖各個字符,從而實現字符、數組和行的高效讀取。

? 默認緩存大小為8k,但可以手動指定緩存的大小,把數據讀取到緩存中,減少每次轉換過程,效率更高

+ BufferedWriter ?將文本寫入字符輸出流,緩沖各個字符,從而提供單個字符、數組和字符串的高效寫入。

? 默認緩存大小為8k,但可以手動指定緩存的大小,把數據寫入到緩存中,減少每次轉換過程,效率更高

### 6)打印流

+ PrintStream 字節打印流

? ~~~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)對象流與序列化

#### ①ObjectOutputStream?

將java對象的基本數據類型和圖形寫入OutputStream

~~~java
package com.demo;

import java.io.*;
//如果一個類創建的對象,需要被序列化,那么該類必須實現Serializable接口
//Serializable是一個標記接口,沒有任何定義,為了告訴JVM該對象可以被序列化
//什么時候對象需要被序列化?
//1.把對象保存到文件中
//2.對象在網絡上傳輸
public class Test8 {
? ? public static void main(String[] args) {
? ? ? ? Dog dog = new Dog("旺財",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?

對以前使用ObjectOutputStream寫入的基本數據和對象進行反序列化。

~~~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)數據流

#### ①DataOutputStream

數據輸出流允許應用程序以適當的方式將基本java數據類型寫入輸出流中。然后,應用程序可以使用數據輸入流將數據讀入。

~~~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

數據輸入流允許應用程序以與機器無關方式從底層輸入流中讀取java基本數據類型。應用程序可以使用數據輸出流寫入稍后由數據輸入流讀取的數據。DataInputStream對于多線程訪問不一定是安全的。線程安全是可選的,它有此類方法的使用者負責。

~~~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 每個文件的大小
? ? ?*/
? ? public static void devision(File targetFile,long cutSize){
? ? ? ? if(targetFile == null)return;
? ? ? ? //計算總分割的文件數
? ? ? ? int num = targetFile.length()%cutSize == 0 ?
? ? ? ? ? ? ? ? (int)(targetFile.length()/cutSize) : (int)((targetFile.length()/cutSize)+1);
? ? ? ? //構造一個文件輸入流
? ? ? ? try {
? ? ? ? ? ? BufferedInputStream bis = new BufferedInputStream(new FileInputStream(targetFile));
? ? ? ? ? ? BufferedOutputStream bos = null;
? ? ? ? ? ? byte [] bytes = null; //每次要讀取的字節數
? ? ? ? ? ? int len = -1;
? ? ? ? ? ? int count = 0; //每一個文件要讀取的次數
? ? ? ? ? ? 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://實驗報告.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://大學課程//web實驗//web實驗報告.doc");
// ? ? ? ?devision(file,1024*512);
? ? ? ? try {
? ? ? ? ? ? InputStream in1 = new FileInputStream(new File("F://1-tempweb實驗報告.doc"));
? ? ? ? ? ? InputStream in2 = new FileInputStream(new File("F://2-tempweb實驗報告.doc"));
? ? ? ? ? ? InputStream in3 = new FileInputStream(new File("F://3-tempweb實驗報告.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)字符串流與管道流

#### ①字符串流

+ 定義:以一個字符串為數據源,來構造一個字符流

+ 作用:在WEB開發中,我們經常要從服務器上獲取數據,數據的返回格式通常是一個字符串(XML,JSON),我們需要把這個字符串構造成一個字符流,然后再用第三方的數據解析器來解析數據。

? ~~~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);
? ? ? ? ? //流標記器
? ? ? ? ? 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);
? ? ? }
? }
? ~~~

#### ②管道流

##?

總結

以上是生活随笔為你收集整理的Java面向对象基础呕心沥血三千字的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。