常見(jiàn)基礎(chǔ)知識(shí)

一树姨、基礎(chǔ)知識(shí):
1蹈集、JVM经宏、JRE和JDK的區(qū)別:
JVM(Java Virtual Machine):java虛擬機(jī)犀暑,用于保證java的跨平臺(tái)的特性。
java語(yǔ)言是跨平臺(tái)烁兰,jvm不是跨平臺(tái)的耐亏。
JRE(Java Runtime Environment):java的運(yùn)行環(huán)境,包括jvm+java的核心類庫(kù)。
JDK(Java Development Kit):java的開(kāi)發(fā)工具,包括jre+開(kāi)發(fā)工具
2沪斟、環(huán)境變量path和classpath的作用是什么广辰?
(1)path是配置Windows可執(zhí)行文件的搜索路徑,即擴(kuò)展名為.exe的程序文件所在的目錄主之,
用于指定DOS窗口命令的路徑择吊。
(2)Classpath是配置class文件所在的目錄,用于指定類搜索路徑槽奕,JVM就是通過(guò)它來(lái)尋找該類的class類文件的几睛。
3、變量有什么用粤攒?為什么要定義變量所森?什么時(shí)候用?
答:變量的作用:用來(lái)存儲(chǔ)數(shù)據(jù)夯接。
為什么要定義變量:用來(lái)不斷的存放同一類型的常量焕济,并可以重復(fù)使用

4、&和&&的區(qū)別?
答:(1)&&會(huì)出現(xiàn)短路盔几,如果可以通過(guò)第一個(gè)表達(dá)式判斷出整個(gè)表達(dá)式的結(jié)果晴弃,則不繼續(xù)后面表達(dá)式的運(yùn)算;
只能操作boolean類型數(shù)據(jù)逊拍;
(2)&不會(huì)出現(xiàn)短路可帽,將整個(gè)表達(dá)式都運(yùn)算。既可以操作boolean數(shù)據(jù)還可以操作數(shù)伐厌。 連接符 age=23&sex=男&address=beijing...

5定嗓、標(biāo)示符命名規(guī)則:面試題 !! (選擇,或判斷)
由數(shù)字(0-9),大小寫(xiě)英文字母注整,以及_和$組成能曾。
(不能是其他特殊字符?! )
不能以數(shù)字開(kāi)頭。
不能使用java(中)關(guān)鍵字來(lái)自定義命名肿轨。

6寿冕、數(shù)據(jù)類型:
(1)基本數(shù)據(jù)類型(4類8種):
整數(shù)類型:byte、short椒袍、int驼唱、long
浮點(diǎn)數(shù)類型:float、double
字符類型:char
布爾類型:boolean(ture false)
(2)引用數(shù)據(jù)類型:

接口
數(shù)組
7驹暑、類型轉(zhuǎn)換
精度從高到低 double float long int short(char) byte
(1)自動(dòng)類型轉(zhuǎn)換 將一個(gè)低精度---?高精度
(2)強(qiáng)制類型轉(zhuǎn)換 將一個(gè)高精度---?低精度(精度會(huì)下降) int i; long y; (Integer)y
8玫恳、java語(yǔ)言的三種技術(shù)架構(gòu)(三個(gè)方向)
JavaEE:企業(yè)版
是為開(kāi)發(fā)企業(yè)環(huán)境下的應(yīng)用程序提供的一套解決方案辨赐。
該技術(shù)體系中包含的技術(shù)如 Servlet、Jsp等京办,主要針對(duì)于Web應(yīng)用程序開(kāi)發(fā)掀序。
JavaSE:標(biāo)準(zhǔn)版
是為開(kāi)發(fā)普通桌面和商務(wù)應(yīng)用程序提供的解決方案。
該技術(shù)體系是其他兩者的基礎(chǔ)惭婿,可以完成一些桌面應(yīng)用程序的開(kāi)發(fā)不恭。
比如Java版的掃雷。
JavaME:小型版
是為開(kāi)發(fā)電子消費(fèi)產(chǎn)品和嵌入式設(shè)備提供的解決方案财饥。
該技術(shù)體系主要應(yīng)用于小型電子消費(fèi)類產(chǎn)品换吧,如手機(jī)中的應(yīng)用程序等。

9钥星、java的跨平臺(tái)性:(Linux)
通過(guò)Java語(yǔ)言編寫(xiě)的應(yīng)用程序在不同的系統(tǒng)平臺(tái)上都可以運(yùn)行沾瓦。
跨平臺(tái)的原因:
只要在需要運(yùn)行java應(yīng)用程序的操作系統(tǒng)上,先安裝一個(gè)Java虛擬機(jī)(JVM Java Virtual Machine)即可打颤。
由JVM來(lái)負(fù)責(zé)Java程序在該系統(tǒng)中的運(yùn)行暴拄。

10、有符號(hào)數(shù)據(jù)的表示法(次重點(diǎn))
原碼编饺,反碼(原碼取反)乖篷,補(bǔ)碼(反碼+1)。
11透且、函數(shù)(方法)
定義:函數(shù)就是定義在類中的具有特定功能的一段獨(dú)立小程序撕蔼。
特點(diǎn):
定義函數(shù)可以將功能代碼進(jìn)行封裝
便于對(duì)該功能進(jìn)行復(fù)用
函數(shù)只有被調(diào)用才會(huì)被執(zhí)行
函數(shù)的出現(xiàn)提高了代碼的復(fù)用性
對(duì)于函數(shù)沒(méi)有具體返回值的情況,返回值類型用關(guān)鍵字void表示秽誊,
那么該函數(shù)中的return語(yǔ)句如果在最后一行可以省略不寫(xiě)鲸沮。
函數(shù)的應(yīng)用兩個(gè)明確:
明確要定義的功能最后的結(jié)果是什么?
明確在定義該功能的過(guò)程中锅论,是否需要未知內(nèi)容參與運(yùn)算
12讼溺、重載:
概念:在同一個(gè)類中,允許存在一個(gè)以上的同名函數(shù)最易,只要它們的參數(shù)個(gè)數(shù)或者參數(shù)類型不同即可怒坯。
特點(diǎn):與返回值類型無(wú)關(guān),只看參數(shù)列表(參數(shù)類型以及參數(shù)個(gè)數(shù))藻懒。
好處:方便于閱讀剔猿,優(yōu)化了程序設(shè)計(jì)。
13嬉荆、數(shù)組:
概念:同一種數(shù)據(jù)類型的集合归敬。
好處:可以自動(dòng)給數(shù)組中的元素從0開(kāi)始編號(hào),方便操作這些元素。
14汪茧、內(nèi)存結(jié)構(gòu):
棧內(nèi)存:用于存儲(chǔ)局部變量椅亚,當(dāng)數(shù)據(jù)使用完,所占空間會(huì)自動(dòng)釋放陆爽。
堆內(nèi)存:數(shù)組和對(duì)象什往,通過(guò)new建立的實(shí)例都存放在堆內(nèi)存中。
方法區(qū):靜態(tài)成員慌闭、構(gòu)造函數(shù)、常量池躯舔、線程池
本地方法區(qū):window系統(tǒng)占用
寄存器:

二驴剔、面向?qū)ο?br> 1、面向?qū)ο笏枷耄?br> (1)概述:面向?qū)ο笫窍鄬?duì)于面向過(guò)程而言的粥庄,面向過(guò)程強(qiáng)調(diào)的是功能丧失,面向?qū)ο髲?qiáng)調(diào)的是將功能封裝進(jìn)對(duì)象,
強(qiáng)調(diào)具備功能的對(duì)象惜互;
(2)思想特點(diǎn):
A:是符合人們思考習(xí)慣的一種思想布讹;
B:將復(fù)雜的事情簡(jiǎn)單化了;
C:將程序員從執(zhí)行者變成了指揮者训堆;

     比如我要達(dá)到某種結(jié)果描验,我就尋找能幫我達(dá)到該結(jié)果的功能的對(duì)象,如我要洗衣服我就買(mǎi)洗衣機(jī)坑鱼,
     至于怎么洗我不管膘流。
(3)特征:
    封裝:隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅對(duì)外提供公共訪問(wèn)方式
    繼承: 多個(gè)類中存在相同屬性和行為時(shí)鲁沥,將這些內(nèi)容抽取到單獨(dú)一個(gè)類中呼股,那么多個(gè)類無(wú)需再定義
          這些屬性和行為,只要繼承那個(gè)類即可画恰。
    多態(tài): 一個(gè)對(duì)象在程序不同運(yùn)行時(shí)刻代表的多種狀態(tài)彭谁,父類或者接口的引用指向子類對(duì)象

2、類和對(duì)象:
類:對(duì)現(xiàn)實(shí)世界中某類事物的描述,是抽象的允扇,概念上的定義缠局。
對(duì)象:事物具體存在的個(gè)體。
3:成員變量和局部變量的區(qū)別(重點(diǎn))
(1)作用域
成員變量:針對(duì)整個(gè)類有效蔼两。
局部變量:只在某個(gè)范圍內(nèi)有效甩鳄。(一般指的就是方法,語(yǔ)句體內(nèi))
(2)存儲(chǔ)位置
成員變量:隨著對(duì)象的創(chuàng)建而存在,隨著對(duì)象的消失而消失额划,存儲(chǔ)在堆內(nèi)存中妙啃。
局部變量:在方法被調(diào)用,或者語(yǔ)句被執(zhí)行的時(shí)候存在,存儲(chǔ)在棧內(nèi)存中揖赴。
當(dāng)方法調(diào)用完馆匿,或者語(yǔ)句結(jié)束后,就自動(dòng)釋放燥滑。
(3)初始值
成員變量:有默認(rèn)初始值渐北。
局部變量:沒(méi)有默認(rèn)初始值,使用前必須賦值铭拧。
4赃蛛、匿名對(duì)象
(1)匿名對(duì)象就是沒(méi)有名字的對(duì)象。是對(duì)象的一種簡(jiǎn)寫(xiě)形式搀菩。
(2)應(yīng)用場(chǎng)景
A:只調(diào)用一次類中的方法呕臂。
B:可以作為實(shí)際參數(shù)在方法傳遞中使用
5、封裝:
指隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié)肪跋,僅對(duì)外提供公共訪問(wèn)方式歧蒋;比如電腦機(jī)箱、筆記本等
好處:
將變化隔離州既;
方便使用谜洽;
提高復(fù)用性;
提高安全性
6吴叶、關(guān)鍵字private:封裝在代碼中的體現(xiàn)
(1)私有的意思阐虚,權(quán)限修飾符
(2)用來(lái)修飾成員變量和成員函數(shù)
(3)用private修飾的成員只在本類中有效
(4)私有是封裝的一種體現(xiàn)
7、構(gòu)造方法:
(1)特點(diǎn):
方法名與類名相同
沒(méi)有返回類型
沒(méi)有返回值
(2)作用:構(gòu)造函數(shù)是用于創(chuàng)建對(duì)象晤郑,并對(duì)其進(jìn)行初始化賦值敌呈,對(duì)象一建立就自動(dòng)調(diào)用相對(duì)應(yīng)的構(gòu)造函數(shù),
(3)構(gòu)造方法的注意事項(xiàng):
A:如果一個(gè)自定義類沒(méi)有構(gòu)造方法造寝,系統(tǒng)會(huì)默認(rèn)給出一個(gè)無(wú)參構(gòu)造方法磕洪。
B:如果一個(gè)自定義類提供了構(gòu)造方法,那么诫龙,系統(tǒng)將不再給出無(wú)參構(gòu)造方法析显。
這個(gè)時(shí)候,你可以不使用無(wú)參構(gòu)造方法签赃。
如果你想使用谷异,那么,就必須手動(dòng)給出無(wú)參構(gòu)造方法锦聊。

    建議:一般情況下歹嘹,我們的自定義類都要手動(dòng)給出無(wú)參構(gòu)造方法。
(4)構(gòu)造方法和成員方法的區(qū)別
    A:格式區(qū)別
        構(gòu)造方法和類名相同孔庭,并且沒(méi)有返回類型尺上,也沒(méi)有返回值材蛛。
        普通成員方法可以任意起名,必須有返回類型怎抛,可以沒(méi)有返回值卑吭。
    B:作用區(qū)別
        構(gòu)造方法用于創(chuàng)建對(duì)象,并進(jìn)行初始化值马绝。
        普通成員方法是用于完成特定功能的豆赏。
    C:調(diào)用區(qū)別
        構(gòu)造方法是在創(chuàng)建對(duì)象時(shí)被調(diào)用的,一個(gè)對(duì)象建立富稻,只調(diào)用一次相應(yīng)構(gòu)造函數(shù)
        普通成員方法是由創(chuàng)建好的對(duì)象調(diào)用权纤,可以調(diào)用多次

8遣疯、構(gòu)造代碼塊:
(1)作用:給對(duì)象進(jìn)行初始化矢空,對(duì)象一建立就執(zhí)行芒炼,而且優(yōu)先于構(gòu)造函數(shù)執(zhí)行
(2)構(gòu)造代碼塊和構(gòu)造函數(shù)的區(qū)別:
構(gòu)造代碼塊是給所有不同對(duì)象的共性進(jìn)行統(tǒng)一初始化
構(gòu)造函數(shù)是給對(duì)應(yīng)的對(duì)象進(jìn)行初始化
9毫别、this關(guān)鍵字
(1)this關(guān)鍵字代表本類對(duì)象的一個(gè)引用踢故,誰(shuí)調(diào)用this所在的方法运挫,this就代表誰(shuí)
(2)this的使用場(chǎng)景
A:用于區(qū)分同名成員變量和局部變量旗们;
B:在定義函數(shù)時(shí)廷痘,該函數(shù)內(nèi)部要用到調(diào)用該函數(shù)的對(duì)象時(shí)蔓涧,因?yàn)榇藭r(shí)對(duì)象還沒(méi)建立,故this代表此對(duì)象
B:構(gòu)造函數(shù)間調(diào)用
**這個(gè)時(shí)候笋额,this(參數(shù))必須作為第一條語(yǔ)句存在元暴。
10、Person p = new Person();在內(nèi)存中做了哪些事情兄猩。
(1)將Person.class文件加載進(jìn)內(nèi)存中茉盏。
(2)如果p定義在主方法中,那么枢冤,就會(huì)在楌蹋空間開(kāi)辟一個(gè)變量空間p。
(3)在堆內(nèi)存給對(duì)象分配空間淹真。
(4)對(duì)對(duì)象中的成員進(jìn)行默認(rèn)初始化讶迁。
(5)對(duì)對(duì)象中的成員進(jìn)行顯示初始化。
(6)調(diào)用構(gòu)造代碼塊對(duì)對(duì)象進(jìn)行初始化核蘸。(如果沒(méi)有就不執(zhí)行)
(7)調(diào)用構(gòu)造方法對(duì)對(duì)象進(jìn)行初始化巍糯。對(duì)象初始化完畢。
(8)將對(duì)象的內(nèi)存地址賦值給p變量客扎,讓p變量指向該對(duì)象祟峦。
11、static關(guān)鍵字:
(1)靜態(tài)的意思徙鱼,用來(lái)修飾成員變量和成員函數(shù)
(2)靜態(tài)的特點(diǎn):
隨著類的加載而加載
優(yōu)先于對(duì)象存在
對(duì)所有對(duì)象共享
可以被類名直接調(diào)用
(3)靜態(tài)的注意事項(xiàng)
A:靜態(tài)方法只能訪問(wèn)靜態(tài)成員
為什么:因?yàn)殪o態(tài)的內(nèi)容是隨著類的加載而加載宅楞,它是先進(jìn)內(nèi)存的。
B:靜態(tài)方法中不能使用this,super關(guān)鍵字
C:主方法是靜態(tài)的
public static void main(String[] args)
public:公共的意思,是最大權(quán)限修飾符咱筛。
static:由于jvm調(diào)用main方法的時(shí)候搓幌,沒(méi)有創(chuàng)建對(duì)象。
只能通過(guò)類名調(diào)用迅箩。所以溉愁,main必須用static修飾。
void:由于main方法是被jvm調(diào)用饲趋,不需要返回值拐揭。用void修飾。
main:main是主要的意思奕塑,所以jvm采用了這個(gè)名字堂污。是程序的入口。

        String[]:字符串?dāng)?shù)組
        args:數(shù)組名

        在運(yùn)行的時(shí)候龄砰,通過(guò)java命令給args數(shù)組賦值盟猖。
        格式:java MainTest hello world itcast
(4)靜態(tài)變量和成員變量的區(qū)別
    A:調(diào)用方式
        靜態(tài)變量也稱為類變量,可以直接通過(guò)類名調(diào)用换棚。也可以通過(guò)對(duì)象名調(diào)用式镐。
        這個(gè)變量屬于類。
        成員變量也稱為實(shí)例變量固蚤,只能通過(guò)對(duì)象名調(diào)用娘汞。這個(gè)變量屬于對(duì)象。
    B:存儲(chǔ)位置
        靜態(tài)變量存儲(chǔ)在方法區(qū)長(zhǎng)中的靜態(tài)區(qū)夕玩。
        成員變量存儲(chǔ)在堆內(nèi)存你弦。
    C:生命周期
        靜態(tài)變量隨著類的加載而存在,隨著類的消失而消失燎孟。生命周期長(zhǎng)禽作。
        成員變量隨著對(duì)象的創(chuàng)建而存在,隨著對(duì)象的消失而消失缤弦。
    D:與對(duì)象的相關(guān)性
        靜態(tài)變量是所有對(duì)象共享的數(shù)據(jù)领迈。
        成員變量是每個(gè)對(duì)象所特有的數(shù)據(jù)。
(5)靜態(tài)的優(yōu)點(diǎn)和弊端
    優(yōu)點(diǎn):
    對(duì)對(duì)象的共享數(shù)據(jù)進(jìn)行單獨(dú)空間的存儲(chǔ)碍沐,節(jié)省內(nèi)存狸捅,沒(méi)有必要每個(gè)對(duì)象都存儲(chǔ)一份
    可直接被類名調(diào)用
    弊端:
    生命周期過(guò)長(zhǎng),隨著類的消失而消失
    訪問(wèn)出現(xiàn)權(quán)限累提,即靜態(tài)雖好但只能訪問(wèn)靜態(tài)
(6)什么使用使用靜態(tài)呢尘喝?
    A:當(dāng)所有對(duì)象共享某個(gè)數(shù)據(jù)的時(shí)候,就把這個(gè)成員變量定義為靜態(tài)修飾的斋陪。
    B:當(dāng)某個(gè)方法沒(méi)有訪問(wèn)該類中的非靜態(tài)成員朽褪,就可以把這個(gè)方法定義為靜態(tài)修飾置吓。

    靜態(tài)的生命周期比較長(zhǎng),所以一般不推薦使用缔赠。
(7)靜態(tài)代碼塊
    A:它只執(zhí)行一次衍锚,它比main還先執(zhí)行。
    B:執(zhí)行順序
        靜態(tài)代碼塊--構(gòu)造代碼塊--構(gòu)造方法

12嗤堰、制作API(次重點(diǎn))
API(全拼):Application Program Interface 應(yīng)用程序編程接口戴质。
(1)類中的內(nèi)容需要用文檔注釋。
(2)使用JDK\bin目錄下的javadoc工具踢匣。
格式:javadoc -d 目錄 -author -version ArrayTool.java
13告匠、單例設(shè)計(jì)模式:
(1)設(shè)計(jì)模式:
解決某類問(wèn)題行之有效的方法,是一種思想离唬,是規(guī)律的總結(jié)
(2)用來(lái)保證某個(gè)類在內(nèi)存中只有一個(gè)對(duì)象
(3)保證唯一性的思想及步驟
**為了避免其他程序建立該類對(duì)象后专,先禁止其他程序建立該類對(duì)象,即將構(gòu)造函數(shù)私有化
**為了其他程序訪問(wèn)到該類對(duì)象输莺,須在本類中創(chuàng)建一個(gè)該類私有對(duì)象
**為了方便其他程序訪問(wèn)到該類對(duì)象戚哎,可對(duì)外提供一個(gè)公共訪問(wèn)方式

比如API中的Runtime類就是單例設(shè)計(jì)模式。

(4)單例設(shè)計(jì)模式的兩種方式
    A:餓漢式 當(dāng)類加載的時(shí)候嫂用,就創(chuàng)建對(duì)象建瘫。    
    class Student
    {
        private Student(){}
        
        private static final Student s = new Student();
        
        public static Student getInstance()
        {
            return s;
        }
    }
    B:懶漢式 當(dāng)使用的使用,才去創(chuàng)建對(duì)象尸折。
    class Student
    {
        private Student(){}

        private static final Student s = null;
        
        public static Student getInstance()
        {
            if(s==null) 
            {
                //線程1就進(jìn)來(lái)了,線程2就進(jìn)來(lái)了殷蛇。
                s = new Student();
            }
            return s;
        }
    }
餓漢式和懶漢式的區(qū)別:
    **
    餓漢式是類一加載進(jìn)內(nèi)存就創(chuàng)建好了對(duì)象实夹;
    懶漢式則是類才加載進(jìn)內(nèi)存的時(shí)候,對(duì)象還沒(méi)有存在粒梦,只有調(diào)用了getInstance()方法時(shí)亮航,
    對(duì)象才開(kāi)始創(chuàng)建。
    **
    懶漢式是延遲加載匀们,如果多個(gè)線程同時(shí)操作懶漢式時(shí)就有可能出現(xiàn)線程安全問(wèn)題缴淋,解決線程安全問(wèn)題
    可以加同步來(lái)解決。但是加了同步之后泄朴,每一次都要比較鎖重抖,效率就變慢了,
    所以可以加雙重判斷來(lái)提高程序效率祖灰。
    注:開(kāi)發(fā)常用餓漢式钟沛,因?yàn)轲I漢式簡(jiǎn)單安全。懶漢式多線程的時(shí)候容易發(fā)生問(wèn)題

14局扶、Math類的使用(重點(diǎn))
(1)數(shù)學(xué)操作類:該類沒(méi)有構(gòu)造函數(shù)恨统,方法均為靜態(tài)的
(2)掌握內(nèi)容
A:成員變量
**E:比任何其他值都更接近e(即自然對(duì)數(shù)的底數(shù))的double值叁扫。
**PI:比任何其他值都更接近pi(即圓的周長(zhǎng)與直徑之比)的double值。
B:成員方法
**static double abs(double a)
返回 double 值的絕對(duì)值畜埋。返回絕對(duì)值
**static double ceil(double a)
返回最小的(最接近負(fù)無(wú)窮大)double 值莫绣,該值大于等于參數(shù),并等于某個(gè)整數(shù)悠鞍。
**static double floor(double a)
返回最大的(最接近正無(wú)窮大)double 值对室,該值小于等于參數(shù),并等于某個(gè)整數(shù)狞玛。
**max:返回兩個(gè)值中較大的那個(gè)
**min:返回兩個(gè)值中較小的那個(gè)
**static long round(double a) 返回最接近參數(shù)的 long软驰。
static int round(float a) 返回最接近參數(shù)的 int。
**static double random()
返回帶正號(hào)的 double 值心肪,該值大于等于 0.0 且小于 1.0锭亏。
**static double pow(double a, double b)
返回第一個(gè)參數(shù)的第二個(gè)參數(shù)次冪的值。
**static double sqrt(double a)
返回正確舍入的 double 值的正平方根硬鞍。
15慧瘤、Random類的使用(重點(diǎn))
(1)產(chǎn)生隨機(jī)數(shù)的類
(2)掌握內(nèi)容
A:構(gòu)造方法
**Random() 創(chuàng)建一個(gè)新的隨機(jī)數(shù)生成器。
**Random(long seed) 使用單個(gè) long 種子創(chuàng)建一個(gè)新的隨機(jī)數(shù)生成器固该。
B:成員方法
**int nextInt() 返回下一個(gè)偽隨機(jī)數(shù)锅减,它是此隨機(jī)數(shù)生成器的序列中均勻分布的 int 值。
**int nextInt(int n) 返回一個(gè)偽隨機(jī)數(shù)伐坏,它是取自此隨機(jī)數(shù)生成器序列的怔匣、
在 0(包括)和指定值(不包括)之間均勻分布的 int 值。
16桦沉、Scanner類的使用
(1)可以獲取從鍵盤(pán)的輸入數(shù)據(jù)
(2)掌握內(nèi)容
構(gòu)造方法:
Scanner(InputStream source) 構(gòu)造一個(gè)新的 Scanner每瞒,它生成的值是從指定的輸入流掃描的。
如:Scanner sc = new Scanner(System.in);
方法摘要
sc.nextInt();獲取整型數(shù)據(jù)
sc.nextLine();獲取字符串?dāng)?shù)據(jù)
17纯露、繼承(重點(diǎn))
(1)把很多類的相同特征和行為進(jìn)行抽取剿骨,用一個(gè)類來(lái)描述。讓多個(gè)類和這個(gè)類產(chǎn)生一個(gè)關(guān)系埠褪。
這樣的話浓利,多個(gè)類就可以省略很多代碼缴渊。這個(gè)關(guān)系就是繼承珍逸。java中用extends關(guān)鍵字表示。
(2)繼承的體系結(jié)構(gòu)
A:多個(gè)具體的對(duì)象孽糖,不斷的向上抽取共享的內(nèi)容渴语,最終形成了一個(gè)體系羽资。這個(gè)體系叫做繼承體系。
B:繼承體系的學(xué)習(xí)和使用原則
**學(xué)習(xí)頂層的內(nèi)容遵班。因?yàn)樗钦麄€(gè)體系的共性內(nèi)容屠升。
**創(chuàng)建子類使用潮改。也就是使用底層的具體對(duì)象。
(3)繼承的特點(diǎn):
A:java中只能單繼承腹暖,沒(méi)有多繼承汇在。
B:java可以有多重(層)繼承。
(4)繼承的好處:
繼承的出現(xiàn)提高了代碼的復(fù)用性脏答。
繼承的出現(xiàn)讓類與類之間產(chǎn)生了關(guān)系糕殉,提供了多態(tài)的前提。
(5)子父類中的成員關(guān)系
A:成員變量
在子類方法中使用一個(gè)變量時(shí):
首先殖告,在方法的局部變量中找這個(gè)變量阿蝶,有則使用。
否則黄绩,在本類中找成員變量羡洁,有則使用。
否則爽丹,在父類中找成員變量筑煮,有則使用。
否則粤蝎,報(bào)錯(cuò)真仲。
B:成員方法
用子類對(duì)象使用一個(gè)方法時(shí)。
首先初澎,在子類中找這個(gè)方法秸应,有則使用。
否則碑宴,在父類中找這個(gè)方法灸眼,有則使用。
否則墓懂,報(bào)錯(cuò)。

    重寫(xiě)和重載的區(qū)別霉囚?
        重載:在同一類中捕仔。方法名相同,參數(shù)列表不同盈罐。重載可以改變返回類型榜跌。
        重寫(xiě):在不同類中(子父類中)。
              方法聲明相同(返回類型盅粪,方法名钓葫,參數(shù)列表均相同)。
    重寫(xiě)需要注意:
        **子類方法的訪問(wèn)權(quán)限要大于等于父類方法的訪問(wèn)權(quán)限票顾。
        **靜態(tài)只能重寫(xiě)靜態(tài)础浮。但是這種情況一般不會(huì)出現(xiàn)帆调。

    構(gòu)造方法
        **子類的實(shí)例化過(guò)程
            ***子類創(chuàng)建對(duì)象時(shí),會(huì)先去創(chuàng)建父類的對(duì)象豆同。
                默認(rèn)是去調(diào)用父類的無(wú)參構(gòu)造方法番刊。
            ***子類構(gòu)造方法中,第一行默認(rèn)是super()
            ***為什么子類中第一行會(huì)默認(rèn)有super()
                因?yàn)樗^承父類的成員使用影锈,使用前這些成員必須初始化芹务,
                而他們是父類的成員,所以鸭廷,必須通過(guò)父類進(jìn)行初始化枣抱。
                所以,會(huì)先創(chuàng)建一個(gè)父類的對(duì)象辆床。
        **當(dāng)父類沒(méi)有無(wú)參構(gòu)造方法時(shí)
            必須使用this或者super調(diào)用其他的構(gòu)造方法佳晶。             
            上轉(zhuǎn)型(上型)
                 1. 定義:如果B類是A類的子類或間接子類,當(dāng)用B類創(chuàng)建對(duì)象b并將這個(gè)對(duì)象b的引用賦給A類對(duì)象時(shí)佛吓,如:
                 A a; 
                 a=new B();
                 OR    
                 A a;
                 B b=new B();
                 a=b;
                則稱A類對(duì)象a是子類B對(duì)象b的上轉(zhuǎn)型對(duì)象
                2.性質(zhì) 對(duì)象b的上轉(zhuǎn)型a的實(shí)體是有子類B創(chuàng)建的宵晚,但是上轉(zhuǎn)型對(duì)象會(huì)失去子類B的一些屬性和功能。
                上轉(zhuǎn)型對(duì)象具有一下特點(diǎn):         
                上轉(zhuǎn)型對(duì)象不能使用子類新增的方法维雇。即為較子類B失去一些屬性和功能淤刃,這些屬性和功能是新增的。
                上轉(zhuǎn)型對(duì)象可以操縱子類繼承的隱藏的成員變量吱型。


(6)this和super的區(qū)別
    this:代表本類對(duì)象的引用逸贾。
    super:代表父類的存儲(chǔ)空間。

18津滞、final關(guān)鍵字(重點(diǎn))
(1)最終的意思铝侵,可以用于修飾類,方法触徐,變量咪鲜。
(2)final修飾的類不能被繼承。
final修飾的方法不能被重寫(xiě)撞鹉。
final修飾的變量是一個(gè)常量疟丙。只能被賦值一次。
內(nèi)部類只能訪問(wèn)被final修飾的局部變量鸟雏。
19享郊、抽象類(重點(diǎn))
(1)多個(gè)類有相同的方法聲明,但是方法體不一樣孝鹊。這個(gè)時(shí)候炊琉,我們考慮把方法聲明進(jìn)行抽取。
讓子類繼承后又活,自己去實(shí)現(xiàn)方法體苔咪。沒(méi)有方法體的方法锰悼,我們需要用抽象標(biāo)志下。
抽象的關(guān)鍵字是:abstract悼泌。
(2)抽象類:
該方法稱為抽象方法松捉,包含抽象方法的類就是抽象類。
(3)抽象類的特點(diǎn):
A:抽象類和抽象方法都要用abstract進(jìn)行修飾
B:抽象類不能被實(shí)例化
C:抽象類中不一定有抽象方法馆里,但是隘世,有抽象方法的類一定是抽象類。
(4)抽象類中數(shù)據(jù)的特點(diǎn)
A:成員變量
抽象類中可以有變量鸠踪,也可以有常量丙者。
B:成員方法
抽象類中可以有抽象方法,也可以有非抽象方法营密。
C:構(gòu)造方法
抽象類是一個(gè)類械媒,所以,它有構(gòu)造方法评汰。
雖然本身不能實(shí)例化纷捞。但是可以給子類實(shí)例化使用。
(5)抽象類中的問(wèn)題
A:抽象類中是否有構(gòu)造方法被去?能不能被實(shí)例化主儡?如果不能,為什么有構(gòu)造方法惨缆?
抽象類有構(gòu)造方法糜值。
抽象類不能被實(shí)例化。
抽象類中的構(gòu)造方法供子類實(shí)例化調(diào)用坯墨。
B:抽象關(guān)鍵字abstract不可以和哪些關(guān)鍵字共存寂汇?
**private:
私有內(nèi)容子類繼承不到,所以捣染,不能重寫(xiě)骄瓣。
但是abstract修飾的方法,要求被重寫(xiě)耍攘。兩者沖突榕栏。
**final
final修飾的方法不能被重寫(xiě)。
而abstract修飾的方法少漆,要求被重寫(xiě)。兩者沖突硼被。
**static
假如一個(gè)抽象方法能通過(guò)static修飾示损,那么這個(gè)方法,就可以直接通過(guò)類名調(diào)用嚷硫。
而抽象方法是沒(méi)有方法體的检访,這樣的調(diào)用無(wú)意義始鱼。所以,不能用static修飾脆贵。
C:抽象類中可不可以沒(méi)有抽象方法医清?如果可以,這樣的類有什么用嗎卖氨?
抽象類可以沒(méi)有抽象方法会烙。
抽象類中沒(méi)有抽象方法的作用,只是為了不讓別的類建立該抽象類對(duì)象筒捺。這個(gè)在awt中有體現(xiàn)柏腻。
20、接口interface
(1)當(dāng)一個(gè)類中的方法都是抽象的時(shí)候系吭,java提供了另一種表示方式五嫂,叫接口。
用interface關(guān)鍵字表示肯尺。類與接口關(guān)系用implements表示沃缘。
(2)接口的成員特點(diǎn)
A:成員變量
是常量,默認(rèn)修飾 public static final
B:成員方法
都是抽象的则吟,默認(rèn)修飾 public abstract
(3)關(guān)系
A:類與類的關(guān)系
是繼承關(guān)系槐臀。類與類只能單繼承娩鹉,可以多重繼承扛伍。
B:類和接口的關(guān)系
是實(shí)現(xiàn)關(guān)系。類可以多實(shí)現(xiàn)接口撮胧。
類在繼承一個(gè)類的同時(shí)寨昙,可以實(shí)現(xiàn)多個(gè)接口讥巡。
C:接口和接口的關(guān)系
是繼承關(guān)系。接口可以多繼承接口舔哪。
(4)接口的特點(diǎn)
A:是對(duì)外暴露的規(guī)則
B:是功能的擴(kuò)展
C:接口的出現(xiàn)降低耦合性欢顷。
耦合(類與類之間的關(guān)系)
內(nèi)聚(類完成功能的能力)
編程規(guī)范:低耦合,高內(nèi)聚捉蚤。
D:接口可以多實(shí)現(xiàn)抬驴。如:CPU和主板、筆記本的USB插口缆巧、插座
(5)接口和抽象類的區(qū)別
A:抽象類只能被單繼承
接口可以多實(shí)現(xiàn),接口的出現(xiàn)避免了多繼承的局限性布持。
B:抽象類中的數(shù)據(jù)特點(diǎn):
成員變量:可以是變量,也可以是常量
成員方法:可以是抽象方法陕悬,也可以是非抽象方法
構(gòu)造方法:有構(gòu)造方法
接口中的數(shù)據(jù)特點(diǎn):
成員變量:是常量题暖。默認(rèn)修飾 public static final
成員方法:都是抽象方法。都有默認(rèn)修飾 public abstract
構(gòu)造方法:沒(méi)有構(gòu)造方法
C:抽象類中定義的是繼承體系中的共性功能。
接口中定義的是繼承體系中的擴(kuò)展功能胧卤。
D:抽象類被繼承是"is a"關(guān)系:xx是yy的一種
接口被實(shí)現(xiàn)是"like a"關(guān)系:xx像yy的一種
21唯绍、多態(tài):
(1)同一個(gè)對(duì)象,在程序不同時(shí)刻的多種運(yùn)行狀態(tài)枝誊。舉例:動(dòng)物况芒,狗是狗,狗是動(dòng)物叶撒。水(氣態(tài)绝骚,液態(tài),固態(tài)){ 多個(gè)不同對(duì)象痊乾,對(duì)統(tǒng)一消息作出不同的響應(yīng)皮壁。也即是
,在父類里聲明一個(gè)未實(shí)行的方法哪审,在子類調(diào)用時(shí)蛾魄,重寫(xiě)方法時(shí)
可根據(jù)子類自己的特征或行為去重寫(xiě)此方法}
(2)多態(tài)前提
A:存在著繼承或者實(shí)現(xiàn)關(guān)系
B:有方法的重寫(xiě)
C:父類(接口)引用指向子類(實(shí)現(xiàn))對(duì)象
(3)多態(tài)的好處和弊端:
好處:多態(tài)的存在提高了程序的擴(kuò)展性和后期可維護(hù)性
弊端:雖然可以預(yù)先使用,但是只能訪問(wèn)父類中已有的功能湿滓,運(yùn)行的是后期子類的功能內(nèi)容滴须。
不能預(yù)先使用子類中定義的特有功能。
(4)多態(tài)中對(duì)象調(diào)用成員的特點(diǎn)
Fu f = new Zi();

    A:成員變量
        編譯看左邊叽奥,運(yùn)行看左邊
    B:成員方法 
        編譯看左邊扔水,運(yùn)行看右邊
    C:靜態(tài)方法
        編譯看左邊,運(yùn)行看左邊
(5)多態(tài)的思想
    指揮同一批對(duì)象做事情朝氓。舉例:帶兵打仗魔市,下課等。

22赵哲、instanceof關(guān)鍵字
A:用于判斷某個(gè)對(duì)象是否是某種類型待德。
B:格式
對(duì)象名 instanceof 子類(實(shí)現(xiàn))名
23、Object類:
(1)是所有類的根類枫夺,超類将宪。
java中提供的類以及我們自定義的類都直接或者間接的繼承自O(shè)bject類。
(2)Object類中的方法
A:void finalize()
當(dāng)垃圾回收器確定不存在對(duì)該對(duì)象的更多引用時(shí)橡庞,由對(duì)象的垃圾回收器調(diào)用此方法较坛。
B:Class getClass()
獲取對(duì)象的字節(jié)碼文件的描述類,后面再講反射的時(shí)候還會(huì)在說(shuō)這個(gè)類扒最。
String name = s.getClass().getName();
C:int hashCode()
獲取對(duì)象的哈希值丑勤。其實(shí)就是對(duì)象的內(nèi)存地址值十進(jìn)制表示
D:String toString()
返回對(duì)象的字符串表示。
表示格式:
getClass().getName()+"@"+Integer.toHexString(hashCode());

      一般我們輸出對(duì)象名的時(shí)候吧趣,其實(shí)底層調(diào)用的就是該對(duì)象的toString()方法法竞。
      這種返回沒(méi)有意義除呵,所以,我們會(huì)重寫(xiě)這個(gè)方法爪喘,顯示類的成員變量信息。
    E:boolean equals(Object obj)
      用于比較兩個(gè)對(duì)象的地址值是否相同纠拔。
      我們獲取對(duì)象后秉剑,比較它的地址值意義不大。所以也會(huì)對(duì)這個(gè)方法進(jìn)行重寫(xiě)稠诲。
      重寫(xiě)要完成什么功能侦鹏,是根據(jù)需求定的。
(3)==和equals的用法:
    A:==怎么用臀叙?
        **可以用于比較基本數(shù)據(jù)類型略水,比較的就是基本數(shù)據(jù)類型的值是否相等。
        **可以用于比較引用數(shù)據(jù)類型劝萤,比較的是對(duì)象的地址值是否相等渊涝。
    B:equals怎么用?
        equals只能用于比較引用數(shù)據(jù)類型的床嫌。
        **Object提供的equals是用于比較對(duì)象地址值是否相同跨释。
        **自定義類中,如果重寫(xiě)了equals方法厌处,那么就是按照你自己的需求來(lái)比較的鳖谈。

24、package關(guān)鍵字
(1)包:其實(shí)就是文件夾阔涉。用于區(qū)分不同包下相同的類名缆娃。
(2)好處:
A:對(duì)類文件進(jìn)行分類管理。
B:給類提供了多層命名空間
aaa.Demo
bbb.Demo
C:寫(xiě)在程序文件的第一行瑰排。
D:包也是一種封裝形式贯要。
25、import關(guān)鍵字
(1)導(dǎo)入包的關(guān)鍵字
(2)格式:
import 包名;
(3)注意:
A:一個(gè)程序文件中只有一個(gè)package凶伙,可以有多個(gè)import郭毕。
B:用來(lái)導(dǎo)包中的類,不導(dǎo)入包中的包函荣。
C:通常寫(xiě)import mypack.Demo显押,明確自己使用的類。
(4)關(guān)鍵字的順序
類傻挂,包乘碑,導(dǎo)包這些關(guān)鍵的順序。
包 -- > 到包 -- > 類
26金拒、不同修飾符可以修飾哪些內(nèi)容
本類中 同一個(gè)包中 不同包中的子類中 不同包中
private OK
默認(rèn) OK Ok
protected OK Ok OK
public OK Ok OK Ok

        類   構(gòu)造方法    成員變量    成員方法        
private         OK      OK      OK
默認(rèn)      Ok  Ok      Ok      OK
protected       OK      OK      Ok
public          Ok  Ok      OK      OK
static                  OK      Ok
final       Ok          OK      OK
abstract    Ok                  OK

一般格式:
    成員變量:
    權(quán)限修飾符+static/final+數(shù)據(jù)類型+成員變量名
    public static final int NUM = 10;
    
    成員方法:
    權(quán)限修飾符+static/final/abstract+返回類型+方法名

27兽肤、內(nèi)部類(次重點(diǎn))
(1)把一個(gè)類定義在某個(gè)類中的套腹,這個(gè)類就被稱為內(nèi)部類,內(nèi)置類资铡,嵌套類电禀。
(2)訪問(wèn)特點(diǎn):
A:內(nèi)部類可以直接訪問(wèn)外部類中的成員,因?yàn)閮?nèi)部類持有外部類的引用笤休,
格式為:外部類名.this

    B:外部類要想訪問(wèn)內(nèi)部類的成員尖飞,必須創(chuàng)建對(duì)象訪問(wèn)。
(3)內(nèi)部類的訪問(wèn)格式:
    A:當(dāng)內(nèi)部類定義在外部類的成員位置店雅,而且非私有政基,則可以在其他外部類中直接建立內(nèi)部類對(duì)象
      格式:外部類名.內(nèi)部類名  變量名 = new 外部類對(duì)象.內(nèi)部類對(duì)象
        如:Outer.Inner in = new Outer().new Inner()
    B:當(dāng)內(nèi)部類在外部類成員位置,且被static修飾時(shí)
        **外部其他類可直接訪問(wèn)靜態(tài)內(nèi)部類的非靜態(tài)成員
          格式:new 外部類名.內(nèi)部類名().內(nèi)部類成員
          如:new Outer.Inner().function();
        **外部其他類可直接訪問(wèn)靜態(tài)內(nèi)部類的靜態(tài)成員
          格式:new 外部類名.內(nèi)部類名.內(nèi)部類成員
          如:new Outer.Inner.function();
(4)什么使用時(shí)候內(nèi)部類呢闹啦?
    假如有A類和B類沮明,A類想直接訪問(wèn)B類的成員,B類訪問(wèn)A類成員的時(shí)候窍奋,
    需要?jiǎng)?chuàng)建A類對(duì)象進(jìn)行訪問(wèn)荐健,這個(gè)時(shí)候,就可以把A類定義為B類的內(nèi)部類琳袄。
(5)內(nèi)部類的位置
    A:成員位置
        **可以被private修飾(Body摧扇,Heart)
        **可以被static修飾。(它訪問(wèn)的外部類的成員必須是靜態(tài)的)    
    B:局部位置
        **可以直接訪問(wèn)外部類中的成員挚歧,因?yàn)檫€持有外部類的持用
        也可以直接訪問(wèn)局部成員扛稽,但是局部成員要用final修飾。      
    注意:局部?jī)?nèi)部類不能用private和static修飾     
(6)通過(guò)class文件我們就可以區(qū)分是否帶有內(nèi)部類滑负,以及內(nèi)部類的位置
    Outer$Inner:成員內(nèi)部類
    Outer$1Inner:局部?jī)?nèi)部類

28在张、匿名內(nèi)部類(局部?jī)?nèi)部類的簡(jiǎn)寫(xiě)) (重點(diǎn))
(1)前提:繼承一個(gè)類或者實(shí)現(xiàn)一個(gè)接口
(注意不要弄混匿名內(nèi)部類的前提和多態(tài)的前提)
(2)格式:
new 父類名或者接口名()
{
重寫(xiě)父類方法或者實(shí)現(xiàn)接口中的方法。
也可以自定義其他方法矮慕。
};
(3)什么時(shí)候定義匿名內(nèi)部類帮匾?
匿名內(nèi)部類只是為了簡(jiǎn)化書(shū)寫(xiě),匿名內(nèi)部類有局限痴鳄,通常定義匿名內(nèi)部類時(shí)瘟斜,該類方法不超過(guò)3個(gè)
(4)匿名內(nèi)部類的好處和弊端:
好處:簡(jiǎn)化代碼書(shū)寫(xiě)
弊端:
不能直接調(diào)用自己的特有方法
不能執(zhí)行強(qiáng)轉(zhuǎn)換動(dòng)作
如果該類里面方法較多,不允許使用匿名內(nèi)部類
29痪寻、模板設(shè)計(jì)模式:
在定義功能時(shí)螺句,功能的一部分是確定的,有一部分是不確定的橡类,而且確定的部分在使用不確定的部分蛇尚,
可將不確定的部分暴露出去,由該類的子類去完成顾画。
如:求一段程序的運(yùn)行時(shí)間例子取劫。
30匆笤、異常
(1)程序運(yùn)行過(guò)程中的不正常現(xiàn)象就叫異常谱邪。
(2)導(dǎo)致程序運(yùn)行不正常的現(xiàn)象有很多炮捧,所以,就有很多的異常對(duì)象惦银。
而這些異常對(duì)象存在著共性的內(nèi)容寓盗,所以,可以不斷的進(jìn)行抽取璧函。最終形成了異常的體系結(jié)構(gòu)。
異常體系的根類是:Throwable
Throwable:
|--Error:重大的問(wèn)題基显,我們處理不了谅摄。也不需要編寫(xiě)代碼處理秘症。比如說(shuō)內(nèi)存溢出。
|--Exception:一般性的錯(cuò)誤,是需要我們編寫(xiě)代碼進(jìn)行處理的抢蚀。
|--RuntimeException:運(yùn)行時(shí)異常,這個(gè)我們也不需要處理拌汇。
其實(shí)就是為了讓他在運(yùn)行時(shí)出問(wèn)題瞧预,然后我們回來(lái)修改代碼。
(3)異常的分類
異常有兩種:
編譯時(shí)被檢測(cè)異常:
該異常在編譯時(shí)榨惰,如果沒(méi)有處理(沒(méi)有拋也沒(méi)有try)拜英,編譯失敗。
該異常被標(biāo)識(shí)琅催,代表這可以被處理居凶。
運(yùn)行時(shí)異常(編譯時(shí)不檢測(cè))
在編譯時(shí),不需要處理藤抡,編譯器不檢查侠碧。
該異常的發(fā)生,建議不處理缠黍,讓程序停止弄兜。需要對(duì)代碼進(jìn)行修正。
(4)異常體系的特點(diǎn):
異常體系中的所有類及其子類對(duì)象都具備可拋性瓷式。也就是說(shuō)可以被throw和throws關(guān)鍵字所操作替饿。
(5)main方法是如何處理異常的。
A:在main里面編寫(xiě)代碼進(jìn)行處理
B:交給jvm自己進(jìn)行處理贸典。采用的是jvm的默認(rèn)處理方式盛垦。
其實(shí)就是相當(dāng)于調(diào)用了異常對(duì)象的printStackTrace()方法。
(6)Throwable類的學(xué)習(xí)
getMessage():獲取異常信息瓤漏,返回字符串腾夯。
toString():獲取異常類名和異常信息颊埃,返回字符串。
printStackTrace():獲取異常類名和異常信息蝶俱,以及異常出現(xiàn)在程序中的位置班利。返回值void。
(7)異常的處理·
A:try...catch...finally
基本格式:
try
{
可能出現(xiàn)異常的代碼
}
catch(異常對(duì)象)
{
異常處理代碼
}
finally
{
釋放資源
}

    變形格式:
        try...catch
        try...catch...catch...
        try...catch...catch...finally
    **多個(gè)異常同時(shí)被捕獲的時(shí)候榨呆,記住一個(gè)原則:
        先逮小的罗标,再逮大的。
    **finally:永遠(yuǎn)被執(zhí)行积蜻,除非退出jvm闯割。System.exit(0);
        面試題2個(gè)。
        ***:final,finally,finalize區(qū)別竿拆。
           final是最終的意思宙拉。它可以用于修飾類,成員變量丙笋,成員方法谢澈。
           它修飾的類不能被繼承,它修飾的變量時(shí)常量御板,它修飾的方法不能被重寫(xiě)锥忿。

           finally:是異常處理里面的關(guān)鍵字。
           它其中的代碼永遠(yuǎn)被執(zhí)行怠肋。特殊情況:在執(zhí)行它之前jvm退出敬鬓。System.exit(0);

           finalize:是Object類中的一個(gè)方法。
           它是于垃圾回收器調(diào)用的方式笙各。

        ***:假如catch中有return語(yǔ)句列林, finally里中的代碼會(huì)執(zhí)行嗎?
           是在return前酪惭,還是在return后呢希痴?
           會(huì),在return前執(zhí)行finally里面的代碼春感。
(8)Exception和RuntimeException的區(qū)別
    A:Exception:一般性的錯(cuò)誤砌创,是需要我們編寫(xiě)代碼進(jìn)行處理的。  
    B:RuntimeException:運(yùn)行時(shí)異常鲫懒,這個(gè)我們也不需要處理嫩实。
                   其實(shí)就是為了讓他在運(yùn)行時(shí)出問(wèn)題,然后我們回來(lái)修改代碼窥岩。
        在用throws拋出一個(gè)的時(shí)候甲献,如果這個(gè)異常是屬于RuntimeException的體系的時(shí)候,
        我們?cè)谡{(diào)用的地方可以不用處理颂翼。(RuntimeException和RuntimeException的子類)
        
        在用throws拋出一個(gè)的時(shí)候晃洒,如果這個(gè)異常是屬于Exception的體系的時(shí)候慨灭,
        我們?cè)谡{(diào)用的地方必須進(jìn)行處理或者繼續(xù)拋出。
(9)自定義異常
    定義類繼承Exception或者RuntimeException
    1,為了讓該自定義類具備可拋性球及。
    2氧骤,讓該類具備操作異常的共性方法。
    class MyExcepiton extends Exception
    {
        MyExcepiton(){}

        MyExcepiton(String message)
        {
            super(message);
        }
    }

    class MyException extends RuntimeException
    {
        MyExcepiton(){}

        MyExcepiton(String message)
        {
            super(message);
        }
    }
(10)throws和throw的區(qū)別
    A:有throws的時(shí)候可以沒(méi)有throw吃引。
       有throw的時(shí)候筹陵,如果throw拋的異常是Exception體系,那么必須有throws在方法上聲明镊尺。
    B:throws用于方法的聲明上朦佩,其后跟的是異常類名,后面可以跟多個(gè)異常類庐氮,之間用逗號(hào)隔開(kāi)
       throw用于方法體中语稠,其后跟的是一個(gè)異常對(duì)象名

三、多線程:
1旭愧、進(jìn)程和線程:
進(jìn)程:正在進(jìn)行的程序。每一個(gè)進(jìn)程執(zhí)行都有一個(gè)執(zhí)行順序宙暇,該順序是一個(gè)執(zhí)行路徑输枯,或者叫一個(gè)控制單元。
線程:進(jìn)程內(nèi)部的一條執(zhí)行路徑或者一個(gè)控制單元占贫。
兩者的區(qū)別:
一個(gè)進(jìn)程至少有一個(gè)線程
進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元桃熄,而多個(gè)線程共享內(nèi)存;
2型奥、jvm多線程的啟動(dòng)是多線程嗎瞳收?
java的虛擬機(jī)jvm啟動(dòng)的是單線程,就有發(fā)生內(nèi)存泄露的可能厢汹,而我們使用java程序沒(méi)出現(xiàn)這樣的問(wèn)題螟深,
也就是jvm啟動(dòng)至少有兩個(gè)線程,一個(gè)執(zhí)行java程序烫葬,一個(gè)執(zhí)行垃圾回收界弧。所以是多線程。
2搭综、多線程的優(yōu)勢(shì):
解決了多部分同時(shí)運(yùn)行的問(wèn)題垢箕,提高效率
3、線程的弊端:
線程太多會(huì)導(dǎo)致效率的降低兑巾,因?yàn)榫€程的執(zhí)行依靠的是CPU的來(lái)回切換条获。
4、什么叫多線程:
一個(gè)進(jìn)程中有多個(gè)線程蒋歌,稱為多線程帅掘。
5委煤、實(shí)現(xiàn)多線程的方法:
實(shí)現(xiàn)多線程可以通過(guò)繼承aaaA類和實(shí)現(xiàn)Runnable接口。
(1)繼承Thread
定義一個(gè)類繼承Thread類
復(fù)寫(xiě)Thread類中的public void run()方法锄开,將線程的任務(wù)代碼封裝到run方法中
直接創(chuàng)建Thread的子類對(duì)象素标,創(chuàng)建線程
調(diào)用start()方法,開(kāi)啟線程(調(diào)用線程的任務(wù)run方法)
//另外可以通過(guò)Thread的getName()獲取線程的名稱萍悴。

(2)實(shí)現(xiàn)Runnable接口头遭;
    定義一個(gè)類,實(shí)現(xiàn)Runnable接口癣诱;
    覆蓋接口的public void run()的方法计维,將線程的任務(wù)代碼封裝到run方法中;
    創(chuàng)建Runnable接口的子類對(duì)象
    將Runnabl接口的子類對(duì)象作為參數(shù)傳遞給Thread類的構(gòu)造函數(shù)撕予,創(chuàng)建Thread類對(duì)象
                   (原因:線程的任務(wù)都封裝在Runnable接口子類對(duì)象的run方法中鲫惶。
             所以要在線程對(duì)象創(chuàng)建時(shí)就必須明確要運(yùn)行的任務(wù))。
    調(diào)用start()方法实抡,啟動(dòng)線程欠母。

兩種方法區(qū)別:
    (1)實(shí)現(xiàn)Runnable接口避免了單繼承的局限性
    (2)繼承Thread類線程代碼存放在Thread子類的run方法中
       實(shí)現(xiàn)Runnable接口線程代碼存放在接口的子類的run方法中;
       在定義線程時(shí)吆寨,建議使用實(shí)現(xiàn)Runnable接口赏淌,因?yàn)閹缀跛卸嗑€程都可以使用這種方式實(shí)現(xiàn)

6、創(chuàng)建線程是為什么要復(fù)寫(xiě)run方法啄清?
Thread類用于描述線程六水。Thread類定義了一個(gè)功能,用于存儲(chǔ)線程要運(yùn)行的代碼辣卒,該存儲(chǔ)功能就是run方法掷贾。
7、start()和run方法有什么區(qū)別荣茫?
調(diào)用start方法方可啟動(dòng)線程想帅,而run方法只是thread的一個(gè)普通方法,調(diào)用run方法不能實(shí)現(xiàn)多線程啡莉;
Start()方法:
start方法用來(lái)啟動(dòng)線程,實(shí)現(xiàn)了多線程運(yùn)行,這時(shí)無(wú)需等待run方法體代碼執(zhí)行完畢而直接繼續(xù)執(zhí)行下面的
代碼博脑。通過(guò)調(diào)用Thread類的start()方法來(lái)啟動(dòng)一個(gè)線程,這時(shí)此線程處于就緒(可運(yùn)行)狀態(tài),并沒(méi)有運(yùn)行票罐,
一旦得到cpu時(shí)間片(執(zhí)行權(quán)),就開(kāi)始執(zhí)行run()方法,這里方法run()稱為線程體叉趣,
它包含了要執(zhí)行的這個(gè)線程的內(nèi)容,Run方法運(yùn)行結(jié)束,此線程隨即終止该押。
Run()方法:
run()方法只是Thread類的一個(gè)普通方法,如果直接調(diào)用Run方法,程序中依然只有主線程這一個(gè)線程,
其程序執(zhí)行路徑還是只有一條疗杉,還是要等待run方法體執(zhí)行完畢后才可繼續(xù)執(zhí)行下面的代碼,
這樣就沒(méi)有達(dá)到多線程的目的。
8烟具、線程的幾種狀態(tài):
新建:new一個(gè)Thread對(duì)象或者其子類對(duì)象就是創(chuàng)建一個(gè)線程梢什,當(dāng)一個(gè)線程對(duì)象被創(chuàng)建,但是沒(méi)有開(kāi)啟朝聋,這個(gè)時(shí)候嗡午,
只是對(duì)象線程對(duì)象開(kāi)辟了內(nèi)存空間和初始化數(shù)據(jù)扁藕。
就緒:新建的對(duì)象調(diào)用start方法覆劈,就開(kāi)啟了線程,線程就到了就緒狀態(tài)项阴。
在這個(gè)狀態(tài)的線程對(duì)象言蛇,具有執(zhí)行資格僻他,沒(méi)有執(zhí)行權(quán)。
運(yùn)行:當(dāng)線程對(duì)象獲取到了CPU的資源腊尚。
在這個(gè)狀態(tài)的線程對(duì)象吨拗,既有執(zhí)行資格,也有執(zhí)行權(quán)婿斥。
凍結(jié):運(yùn)行過(guò)程中的線程由于某些原因(比如wait,sleep)劝篷,釋放了執(zhí)行資格和執(zhí)行權(quán)。
當(dāng)然民宿,他們可以回到運(yùn)行狀態(tài)娇妓。只不過(guò),不是直接回到勘高。
而是先回到就緒狀態(tài)峡蟋。
死亡:當(dāng)線程對(duì)象調(diào)用的run方法結(jié)束坟桅,或者直接調(diào)用stop方法华望,就讓線程對(duì)象死亡,在內(nèi)存中變成了垃圾仅乓。
9赖舟、sleep()和wait()的區(qū)別:
(1)這兩個(gè)方法來(lái)自不同的類,sleep()來(lái)自Thread類夸楣,和wait()來(lái)自O(shè)bject類宾抓。
(2)sleep是Thread的靜態(tài)類方法,誰(shuí)調(diào)用的誰(shuí)去睡覺(jué)豫喧,即使在a線程里調(diào)用了b的sleep方法石洗,實(shí)際上還是a去睡覺(jué),
要讓b線程睡覺(jué)要在b的代碼中調(diào)用sleep紧显。而wait()是Object類的非靜態(tài)方法
(3)sleep()釋放資源不釋放鎖讲衫,而wait()釋放資源釋放鎖;
(4)使用范圍:wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用
10孵班、多線程安全問(wèn)題:
(1)原因:當(dāng)程序的多條語(yǔ)句在操作線程共享數(shù)據(jù)時(shí)(如買(mǎi)票例子中的票就是共享資源)涉兽,由于線程的隨機(jī)性導(dǎo)致
一個(gè)線程對(duì)多條語(yǔ)句招驴,執(zhí)行了一部分還沒(méi)執(zhí)行完,另一個(gè)線程搶奪到cpu執(zhí)行權(quán)參與進(jìn)來(lái)執(zhí)行枷畏,
此時(shí)就導(dǎo)致共享數(shù)據(jù)發(fā)生錯(cuò)誤别厘。比如買(mǎi)票例子中打印重票和錯(cuò)票的情況。
(2)解決方法:對(duì)多條操作共享數(shù)據(jù)的語(yǔ)句進(jìn)行同步拥诡,一個(gè)線程在執(zhí)行過(guò)程中其他線程不可以參與進(jìn)來(lái)
11触趴、Java中多線程同步是什么?
同步是用來(lái)解決多線程的安全問(wèn)題的袋倔,在多線程中雕蔽,同步能控制對(duì)共享數(shù)據(jù)的訪問(wèn)。如果沒(méi)有同步宾娜,當(dāng)一個(gè)線程在
修改一個(gè)共享數(shù)據(jù)時(shí)批狐,而另外一個(gè)線程正在使用或者更新同一個(gè)共享數(shù)據(jù),這樣容易導(dǎo)致程序出現(xiàn)錯(cuò)誤的結(jié)果前塔。
12嚣艇、什么是鎖?鎖的作用是什么?
鎖就是對(duì)象
鎖的作用是保證線程同步,解決線程安全問(wèn)題华弓。
持有鎖的線程可以在同步中執(zhí)行食零,沒(méi)有鎖的線程即使獲得cpu執(zhí)行權(quán),也進(jìn)不去寂屏。
13贰谣、同步的前提:
(1)必須保證有兩個(gè)以上線程
(2)必須是多個(gè)線程使用同一個(gè)鎖,即多條語(yǔ)句在操作線程共享數(shù)據(jù)
(3)必須保證同步中只有一個(gè)線程在運(yùn)行
14迁霎、同步的好處和弊端
好處:同步解決了多線程的安全問(wèn)題
弊端:多線程都需要判斷鎖吱抚,比較消耗資源
15、同步的兩種表現(xiàn)形式:
(1)同步代碼塊:
可以指定需要獲取哪個(gè)對(duì)象的同步鎖,使用synchronized的代碼塊同樣需要鎖,但他的鎖可以是任意對(duì)象
考慮到安全問(wèn)題考廉,一般還是使用同一個(gè)對(duì)象秘豹,相對(duì)來(lái)說(shuō)效率較高。

    注意:
    **雖然同步代碼快的鎖可以使任何對(duì)象昌粤,但是在進(jìn)行多線程通信使用同步代碼快時(shí)既绕,
      必須保證同步代碼快的鎖的對(duì)象和,否則會(huì)報(bào)錯(cuò)涮坐。
    **同步函數(shù)的鎖是this凄贩,也要保證同步函數(shù)的鎖的對(duì)象和調(diào)用wait、notify和notifyAll的對(duì)象是
      同一個(gè)對(duì)象袱讹,也就是都是this鎖代表的對(duì)象疲扎。
    格式:
    synchronized(對(duì)象)
    {
        需同步的代碼;
    }
(2)同步函數(shù)
    同步方法是指進(jìn)入該方法時(shí)需要獲取this對(duì)象的同步鎖,在方法上使用synchronized關(guān)鍵字,
    使用this對(duì)象作為鎖评肆,也就是使用了當(dāng)前對(duì)象债查,因?yàn)殒i住了方法,所以相對(duì)于代碼塊來(lái)說(shuō)效率相對(duì)較低瓜挽。
    注:靜態(tài)同步函數(shù)的鎖是該方法所在的類的字節(jié)碼文件對(duì)象盹廷,即類名.class文件
    格式:
    修飾詞 synchronized 返回值類型 函數(shù)名(參數(shù)列表)
    {
        需同步的代碼;
    }

在jdk1.5后,用lock鎖取代了synchronized久橙,個(gè)人理解也就是對(duì)同步代碼塊做了修改俄占,
并沒(méi)有提供對(duì)同步方法的修改,主要還是效率問(wèn)題吧淆衷。

16缸榄、多線程的單例設(shè)計(jì)模式:保證某個(gè)類中內(nèi)存中只有一個(gè)對(duì)象
(1)餓漢式:
class Single
{
private Single(){}//將構(gòu)造函數(shù)私有化,不讓別的類建立該類對(duì)象
private static final Single s=new Single();//自己建立一個(gè)對(duì)象
public static Single getInstance()//提供一個(gè)公共訪問(wèn)方式
{
return s;
}
}
(2)懶漢式:
class Single
{
private Single(){}
private static Single s;
public static Single getInstance()
{
if(s==null)
s=new Single();
return s;
}
}
餓漢式和懶漢式的區(qū)別:
**
餓漢式是類一加載進(jìn)內(nèi)存就創(chuàng)建好了對(duì)象祝拯;
懶漢式則是類加載進(jìn)內(nèi)存的時(shí)候甚带,對(duì)象還沒(méi)有存在,只有調(diào)用了getInstance()方法時(shí)佳头,對(duì)象才開(kāi)始創(chuàng)建鹰贵。
**
懶漢式是延遲加載,如果多個(gè)線程同時(shí)操作懶漢式時(shí)就有可能出現(xiàn)線程安全問(wèn)題康嘉,解決線程安全問(wèn)題
可以加同步來(lái)解決碉输。但是加了同步之后,每一次都要比較鎖亭珍,效率就變慢了敷钾,
所以可以加雙重判斷來(lái)提高程序效率。
如將上述懶漢式的Instance函數(shù)改成同步:
public static Single getInstance()
{
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s=new Single();
}
}
return s;
}
17肄梨、死鎖
兩個(gè)線程對(duì)兩個(gè)同步對(duì)象具有循環(huán)依賴時(shí)阻荒,就會(huì)發(fā)生死鎖。即同步嵌套同步峭范,而鎖卻不同财松。
18瘪贱、wait()纱控、sleep()、notify()菜秦、notifyAll()
wait():使一個(gè)線程處于等待狀態(tài)甜害,并且釋放所持有的對(duì)象的lock。
sleep():使一個(gè)正在運(yùn)行的線程處于睡眠狀態(tài)球昨,是一個(gè)靜態(tài)方法尔店,調(diào)用此方法要捕捉InterruptedException異常。
notify():喚醒一個(gè)處于等待狀態(tài)的線程,注意的是在調(diào)用此方法的時(shí)候嚣州,并不能確切的喚醒某一個(gè)等待狀態(tài)的線程鲫售,
而是由JVM確定喚醒哪個(gè)線程(一般是最先開(kāi)始等待的線程),而且不是按優(yōu)先級(jí)该肴。
Allnotity():喚醒所有處入等待狀態(tài)的線程情竹,注意并不是給所有喚醒線程一個(gè)對(duì)象的鎖,而是讓它們競(jìng)爭(zhēng)匀哄。
18秦效、為什么wait()、notify()涎嚼、notifyAll()這些用來(lái)操作線程的方法定義在Object類中阱州?
(1)這些方法只存在于同步中;
(2)使用這些方法時(shí)必須要指定所屬的鎖法梯,即被哪個(gè)鎖調(diào)用這些方法苔货;
(3)而鎖可以是任意對(duì)象,所以任意對(duì)象調(diào)用的方法就定義在Object中立哑。
19蒲赂、多線程間通訊:
多線程間通訊就是多個(gè)線程在操作同一資源,但是操作的動(dòng)作不同.
(1)為什么要通信
多線程并發(fā)執(zhí)行的時(shí)候, 如果需要指定線程等待或者喚醒指定線程, 那么就需要通信.比如生產(chǎn)者消費(fèi)者的問(wèn)題,
生產(chǎn)一個(gè)消費(fèi)一個(gè),生產(chǎn)的時(shí)候需要負(fù)責(zé)消費(fèi)的進(jìn)程等待,生產(chǎn)一個(gè)后完成后需要喚醒負(fù)責(zé)消費(fèi)的線程,
同時(shí)讓自己處于等待刁憋,消費(fèi)的時(shí)候負(fù)責(zé)消費(fèi)的線程被喚醒滥嘴,消費(fèi)完生產(chǎn)的產(chǎn)品后又將等待的生產(chǎn)線程喚醒,
然后使自己線程處于等待至耻。這樣來(lái)回通信若皱,以達(dá)到生產(chǎn)一個(gè)消費(fèi)一個(gè)的目的。
(2)怎么通信
在同步代碼塊中, 使用鎖對(duì)象的wait()方法可以讓當(dāng)前線程等待, 直到有其他線程喚醒為止.
使用鎖對(duì)象的notify()方法可以喚醒一個(gè)等待的線程尘颓,或者notifyAll喚醒所有等待的線程.
多線程間通信用sleep很難實(shí)現(xiàn)走触,睡眠時(shí)間很難把握。

20疤苹、Lock和Condition
實(shí)現(xiàn)提供比synchronized方法和語(yǔ)句可獲得的更廣泛的鎖的操作互广,可支持多個(gè)相關(guān)的Condition對(duì)象
Lock是個(gè)接口
鎖是控制多個(gè)線程對(duì)共享數(shù)據(jù)進(jìn)行訪問(wèn)的工具。

JDK1.5中提供了多線程升級(jí)的解決方案:
將同步synchonized替換成了顯示的Lock操作卧土,將Object中的wait惫皱、notify、notifyAll替換成了Condition對(duì)象尤莺。
該對(duì)象可以Lock鎖進(jìn)行獲取

Lock的方法摘要:
    void lock()  獲取鎖旅敷。 
    Condition newCondition() 返回綁定到此 Lock 實(shí)例的新 Condition 實(shí)例。 
    void unlock() 釋放鎖颤霎。
Condition方法摘要:
    void await() 造成當(dāng)前線程在接到信號(hào)或被中斷之前一直處于等待狀態(tài)媳谁。
    void signal() 喚醒一個(gè)等待線程涂滴。          
    void signalAll() 喚醒所有等待線程。

21晴音、停止線程:
stop方法已經(jīng)過(guò)時(shí)圆兵,如何停止線程扼雏?
停止線程的方法只有一種,就是run方法結(jié)束。如何讓run方法結(jié)束呢燕偶?
開(kāi)啟多線程運(yùn)行承匣,運(yùn)行代碼通常是循環(huán)體魄懂,只要控制住循環(huán)熊楼,就可以讓run方法結(jié)束,也就是結(jié)束線程觉啊。

    特殊情況:當(dāng)線程屬于凍結(jié)狀態(tài)拣宏,就不會(huì)讀取循環(huán)控制標(biāo)記,則線程就不會(huì)結(jié)束杠人。
    為解決該特殊情況勋乾,可引入Thread類中的Interrupt方法結(jié)束線程的凍結(jié)狀態(tài);
    當(dāng)沒(méi)有指定的方式讓凍結(jié)線程恢復(fù)到運(yùn)行狀態(tài)時(shí)嗡善,需要對(duì)凍結(jié)進(jìn)行清除辑莫,強(qiáng)制讓線程恢復(fù)到運(yùn)行狀態(tài)

22、interrupt:
void interrupt() 中斷線程:
中斷狀態(tài)將被清除罩引,它還將收到一個(gè) InterruptedException
22各吨、守護(hù)線程(后臺(tái)線程)
setDaemon(boolean on):將該線程標(biāo)記為守護(hù)線程或者用戶線程。
當(dāng)主線程結(jié)束袁铐,守護(hù)線程自動(dòng)結(jié)束揭蜒,比如圣斗士星矢里面的守護(hù)雅典娜,
在多線程里面主線程就是雅典娜剔桨,守護(hù)線程就是圣斗士屉更,主線程結(jié)束了,
守護(hù)線程則自動(dòng)結(jié)束洒缀。
當(dāng)正在運(yùn)行的線程都是守護(hù)線程時(shí)瑰谜,java虛擬機(jī)jvm退出;所以該方法必須在啟動(dòng)線程前調(diào)用树绩;

守護(hù)線程的特點(diǎn):
    守護(hù)線程開(kāi)啟后和前臺(tái)線程共同搶奪cpu的執(zhí)行權(quán)萨脑,開(kāi)啟、運(yùn)行兩者都沒(méi)區(qū)別葱峡,
    但結(jié)束時(shí)有區(qū)別砚哗,當(dāng)所有前臺(tái)線程都結(jié)束后龙助,守護(hù)線程會(huì)自動(dòng)結(jié)束砰奕。      

23蛛芥、多線程join方法:
void join() 等待該線程終止。
void join(long millis) 等待該線程終止的時(shí)間最長(zhǎng)為 millis 毫秒军援。
throws InterruptedException
特點(diǎn):當(dāng)A線程執(zhí)行到B線程的join方法時(shí)仅淑,A就會(huì)等待B線程都執(zhí)行完,A才會(huì)執(zhí)行
作用: join可以用來(lái)臨時(shí)加入線程執(zhí)行胸哥;
24涯竟、多線程優(yōu)先級(jí):yield()方法
yield():暫停當(dāng)前正在執(zhí)行的線程對(duì)象,并執(zhí)行其他線程
setPriority(int newPriority):更改線程優(yōu)先級(jí)
int getPriority() 返回線程的優(yōu)先級(jí)空厌。
String toString() 返回該線程的字符串表示形式庐船,包括線程名稱、優(yōu)先級(jí)和線程組

(1)MAX_PRIORITY:最高優(yōu)先級(jí)(10級(jí))
(1)Min_PRIORITY:最低優(yōu)先級(jí)(1級(jí))
(1)Morm_PRIORITY:默認(rèn)優(yōu)先級(jí)(5級(jí))

25嘲更、什么是ThreadLocal類,怎么使用它筐钟?
ThreadLocal類提供了線程局部 (thread-local) 變量。是一個(gè)線程級(jí)別的局部變量赋朦,并非“本地線程”篓冲。
ThreadLocal 為每個(gè)使用該變量的線程,提供了一個(gè)獨(dú)立的變量副本,每個(gè)線程修改副本時(shí)不影響其它線程對(duì)象的副本

下面是線程局部變量(ThreadLocal variables)的關(guān)鍵點(diǎn):
    一個(gè)線程局部變量(ThreadLocal variables)為每個(gè)線程方便地提供了一個(gè)單獨(dú)的變量宠哄。
    ThreadLocal 實(shí)例通常作為靜態(tài)的私有的(private static)字段出現(xiàn)在一個(gè)類中壹将,這個(gè)類用來(lái)關(guān)聯(lián)一個(gè)線程。 
    當(dāng)多個(gè)線程訪問(wèn) ThreadLocal 實(shí)例時(shí)毛嫉,每個(gè)線程維護(hù) ThreadLocal 提供的獨(dú)立的變量副本诽俯。
    常用的使用可在 DAO 模式中見(jiàn)到,當(dāng) DAO 類作為一個(gè)單例類時(shí)承粤,
    數(shù)據(jù)庫(kù)鏈接(connection)被每一個(gè)線程獨(dú)立的維護(hù)惊畏,互不影響。(基于線程的單例)

26密任、什么時(shí)候拋出InvalidMonitorStateException異常?為什么颜启?
調(diào)用 wait ()/notify ()/notifyAll ()中的任何一個(gè)方法時(shí),如果當(dāng)前線程沒(méi)有獲得該對(duì)象的鎖浪讳,
那么就會(huì)拋出 IllegalMonitorStateException 的異常
也就是說(shuō)程序在沒(méi)有執(zhí)行對(duì)象的任何同步塊或者同步方法時(shí)缰盏,
仍然嘗試調(diào)用 wait ()/notify ()/notifyAll ()時(shí)。由于該異常是 RuntimeExcpetion 的子類淹遵,
所以該異常不一定要捕獲(盡管你可以捕獲只要你愿意
作為 RuntimeException口猜,此類異常不會(huì)在 wait (),notify (),notifyAll ()的方法簽名提及。
27透揣、在靜態(tài)方法上使用同步時(shí)會(huì)發(fā)生什么事济炎?
同步靜態(tài)方法時(shí)會(huì)獲取該類的“Class”對(duì)象,所以當(dāng)一個(gè)線程進(jìn)入同步的靜態(tài)方法中時(shí)辐真,
線程監(jiān)視器獲取類本身的對(duì)象鎖须尚,其它線程不能進(jìn)入這個(gè)類的任何靜態(tài)同步方法崖堤。
它不像實(shí)例方法,因?yàn)槎鄠€(gè)線程可以同時(shí)訪問(wèn)不同實(shí)例同步實(shí)例方法耐床。
28密幔、當(dāng)一個(gè)同步方法已經(jīng)執(zhí)行,線程能夠調(diào)用對(duì)象上的非同步實(shí)例方法嗎撩轰?
可以胯甩,一個(gè)非同步方法總是可以被調(diào)用而不會(huì)有任何問(wèn)題。
實(shí)際上堪嫂,Java 沒(méi)有為非同步方法做任何檢查偎箫,鎖對(duì)象僅僅在同步方法或者同步代碼塊中檢查。
如果一個(gè)方法沒(méi)有聲明為同步皆串,即使你在使用共享數(shù)據(jù)Java照樣會(huì)調(diào)用镜廉,而不會(huì)做檢查是否安全,
所以在這種情況下要特別小心愚战。一個(gè)方法是否聲明為同步取決于臨界區(qū)訪問(wèn)(critial section access)娇唯,
如果方法不訪問(wèn)臨界區(qū)(共享資源或者數(shù)據(jù)結(jié)構(gòu))就沒(méi)必要聲明為同步的。
29寂玲、在一個(gè)對(duì)象上兩個(gè)線程可以調(diào)用兩個(gè)不同的同步實(shí)例方法嗎塔插?
不能,因?yàn)橐粋€(gè)對(duì)象已經(jīng)同步了實(shí)例方法拓哟,線程獲取了對(duì)象的對(duì)象鎖想许。
所以只有執(zhí)行完該方法釋放對(duì)象鎖后才能執(zhí)行其它同步方法。
30断序、什么是線程餓死流纹,什么是活鎖?
線程餓死和活鎖雖然不像死鎖一樣是常見(jiàn)的問(wèn)題违诗,但是對(duì)于并發(fā)編程的設(shè)計(jì)者來(lái)說(shuō)就像一次邂逅一樣漱凝。
當(dāng)所有線程阻塞,或者由于需要的資源無(wú)效而不能處理诸迟,不存在非阻塞線程使資源可用茸炒。
JavaAPI 中線程活鎖可能發(fā)生在以下情形:
當(dāng)所有線程在程序中執(zhí)行 Object.wait (0),參數(shù)為 0 的 wait 方法阵苇。
程序?qū)l(fā)生活鎖直到在相應(yīng)的對(duì)象上有線程調(diào)用 Object.notify ()或者 Object.notifyAll ()壁公。
當(dāng)所有線程卡在無(wú)限循環(huán)中。

四绅项、集合框架
1:String類:字符串(重點(diǎn))
(1)多個(gè)字符組成的一個(gè)序列紊册,叫字符串。
生活中很多數(shù)據(jù)的描述都采用的是字符串的快耿。而且我們還會(huì)對(duì)其進(jìn)行操作囊陡。
所以芳绩,java就提供了這樣的一個(gè)類供我們使用。
(2)創(chuàng)建字符串對(duì)象
A:String():無(wú)參構(gòu)造
**舉例:
String s = new String();
s = "hello";
sop(s);
B:String(byte[] bys):傳一個(gè)字節(jié)數(shù)組作為參數(shù) *****
**舉例
byte[] bys = {97,98,99,100,101};
String s = new String(bys);
sop(s);
C:String(byte[] bys,int index,int length):把字節(jié)數(shù)組的一部分轉(zhuǎn)換成一個(gè)字符串 *****
**舉例
byte[] bys = {97,98,99,100,101};
String s = new String(bys,1,2);
sop(s);
D:String(char[] chs):傳一個(gè)字符數(shù)組作為參數(shù) *****
**舉例
char[] chs = {'a','b','c','d','e'};
String s = new String(chs);
sop(s);
E:String(char[] chs,int index,int length):把字符數(shù)組的一部分轉(zhuǎn)換成一個(gè)字符串 *****
**舉例
char[] chs = {'a','b','c','d','e'};
String s = new String(chs,1,2);
sop(s);
F:String(String str):把一個(gè)字符串傳遞過(guò)來(lái)作為參數(shù)
char[] chs = {'a','b','c','d','e'};
String ss = new String(s);
sop(ss);
G:直接把字符串常量賦值給字符串引用對(duì)象(最常用) *****
**舉例
String s = "hello";
sop(s);
(3)面試題
A:請(qǐng)問(wèn)String s = new String("hello");創(chuàng)建了幾個(gè)對(duì)象关斜。
兩個(gè)示括。一個(gè)"hello"字符串對(duì)象铺浇,在方法區(qū)的常量池痢畜;一個(gè)s對(duì)象,在棧內(nèi)存鳍侣。

    B:請(qǐng)寫(xiě)出下面的結(jié)果
        String s1 = new String("abc");
        Strign s2 = new String("abc");
        String s3 = "abc";
        String s4 = "abc";

        sop(s1==s2);  //false
        sop(s1==s3);  //false
        sop(s3==s4);  //true
    C:字符串對(duì)象一旦被創(chuàng)建就不能被改變丁稀。
        指的是字符串常量值不改變。
(4)字符串中各種功能的方法
    A:判斷
    ****    boolean equals(Object anObject):判斷兩個(gè)字符串的內(nèi)容是否相同倚聚,復(fù)寫(xiě)了Object的方法
    ****    boolean equalsIgnoreCase(String anotherString):判斷兩個(gè)字符串的內(nèi)容是否相同线衫,
                                不區(qū)分大小寫(xiě)
    ****    boolean contains(String s):判斷一個(gè)字符串中是否包含另一個(gè)字符串
                    注意:判斷字符串是否包含特殊字符.直接表示為str.contains(".")
        boolean endsWith(String suffix):測(cè)試此字符串是否以指定的后綴結(jié)束
        boolean startsWith(String suffix):測(cè)試此字符串是否以指定的前綴開(kāi)始
        boolean isEmpty():測(cè)試字符串是否為空
    B:獲取
    *****   int length():返回此字符串的長(zhǎng)度
    *****   char charAt(int index):返回指定索引處的 char值
    *****   int indexOf(int ch):返回指定字符在此字符串中第一次出現(xiàn)處的索引。 
        int indexOf(int ch, int fromIndex):返回在此字符串中第一次出現(xiàn)指定字符處的索引惑折,
                           從指定的索引開(kāi)始搜索授账。 
        int indexOf(String str):返回指定子字符串在此字符串中第一次出現(xiàn)處的索引。 
        int indexOf(String str, int fromIndex):返回指定子字符串在此字符串中第一次
                            出現(xiàn)處的索引惨驶,從指定的索引開(kāi)始白热。 
    *** int lastIndexOf(int ch):返回指定字符在此字符串中最后一次出現(xiàn)處的索引。 
        int lastIndexOf(int ch, int fromIndex) 
            返回指定字符在此字符串中最后一次出現(xiàn)處的索引,從指定的索引處開(kāi)始進(jìn)行反向搜索粗卜。 
        int lastIndexOf(String str) 
            返回指定子字符串在此字符串中最右邊出現(xiàn)處的索引屋确。 
        int lastIndexOf(String str, int fromIndex) 
            返回指定子字符串在此字符串中最后一次出現(xiàn)處的索引,從指定的索引開(kāi)始反向搜索续扔。 
    *****   String substring(int beginIndex) (注意:該方法substring的String是小寫(xiě)9ネ巍!纱昧!)
            返回一個(gè)新的字符串刨啸,它是此字符串的一個(gè)子字符串。 
        String substring(int beginIndex, int endIndex) (注意該方法的String是小寫(xiě)J洞唷N赝丁!)
            返回一個(gè)新字符串存璃,它是此字符串的一個(gè)子字符串,包含頭不包含尾仑荐。 
    C:轉(zhuǎn)換
    *****   byte[] getBytes():(很常用!)從字符串到字節(jié)數(shù)組的方法
        void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 
            將字符從此字符串復(fù)制到目標(biāo)字符數(shù)組纵东。 
    *****   char[] toCharArray():(很常用粘招!)從字符串到字符數(shù)組的方法
    ****    static String copyValueOf(char[] data) 
            返回指定數(shù)組中表示該字符序列的 String。 
        static String copyValueOf(char[] data, int offset, int count) 
            返回指定數(shù)組中表示該字符序列的 String偎球。 
    *****   static String valueOf(數(shù)據(jù)類型):把該數(shù)據(jù)類型的數(shù)據(jù)轉(zhuǎn)換成字符串洒扎。
    *** String toLowerCase():把字符串轉(zhuǎn)換成小寫(xiě)
        String toUpperCase():把字符串轉(zhuǎn)換成大寫(xiě)
    *** 字符串的連接
        String concat(String str):將指定字符串連接到此字符串的結(jié)尾辑甜。
    D:替換
        String replace(char oldChar, char newChar):用新字符替換舊字符(替換所有)
        String replace(String target, String replacement):用新的子串換舊串
    E:分割
        String[] split(String regex):根據(jù)指定的字符串把一個(gè)字符串分割成一個(gè)字符串?dāng)?shù)組
    F:  
        String trim():去除字符串的前后空格
    G:  
        int compareTo(String anotherString) 
            按字典順序比較兩個(gè)字符串秉溉。 
        int compareToIgnoreCase(String str) 
            按字典順序比較兩個(gè)字符串窿侈,不考慮大小寫(xiě)。 
(5)練習(xí)
    1:模擬登錄,給三次機(jī)會(huì),并提示還有幾次.
    默認(rèn)的用戶名和密碼為admin墓猎。 區(qū)分大小寫(xiě)胡诗。
    自己從鍵盤(pán)輸入用戶名和密



    2:給定一個(gè)字符串統(tǒng)計(jì),統(tǒng)計(jì)大寫(xiě)字母,小寫(xiě)字母,數(shù)字出現(xiàn)的個(gè)數(shù).
    ***注意:不包括特殊字符
    從鍵盤(pán)輸入一個(gè)不包含特殊字符的字符串(只有26個(gè)字母和0-9組成)邓线。

    3:給定一個(gè)字符串,把它變成首字母大寫(xiě),其他字母小寫(xiě)的字符串.
    從鍵盤(pán)輸入一個(gè)字符串,全部26個(gè)字母組成的煌恢。

    4:子串在整串中出現(xiàn)的次數(shù)骇陈。
    也就是說(shuō):獲取一個(gè)字符串中,指定的字串在該字符串中出現(xiàn)的次數(shù).
    例如:
    "nbasdnbafllgnbahjnbakqqqqlnba"  在這個(gè)字符串中,多有個(gè)nba.

    5:對(duì)字符串中字符進(jìn)行自然順序排序瑰抵。
    "basckd"-->"abcdks"

    先留做思考內(nèi)容:
    6:兩個(gè)字符串的最大相同子串你雌。
    兩個(gè)字符串的最大相同子串。
    比如:
    "sadabcdfghjkl"
    werabcdtyu"

2:StringBuffer
(1)字符串的緩沖區(qū)二汛,是一個(gè)容器婿崭。
(2)它和String的區(qū)別
它是緩沖區(qū)可變長(zhǎng)度的。
(3)構(gòu)造方法
StringBuffer() 構(gòu)造一個(gè)其中不帶字符的字符串緩沖區(qū)肴颊,初始容量為 16 個(gè)字符氓栈。
StringBuffer(int num) 構(gòu)造一個(gè)不帶字符,但具有指定初始容量的字符串緩沖區(qū)苫昌。
StringBuffer(String str) 構(gòu)造一個(gè)字符串緩沖區(qū)颤绕,并將其內(nèi)容初始化為指定的字符串內(nèi)容。
(4)常用方法
A:增加數(shù)據(jù)
**append :添加各種類型的數(shù)據(jù)
**insert : 在容器指定位置插入各種類型的數(shù)據(jù)祟身。
B:刪除數(shù)據(jù)
**deleteCharAt : 刪除指定位置的字符
**delete 還可以用于清空StringBuffer的緩沖區(qū)
C:替換
**replace
D:獲取
**charAt
E:長(zhǎng)度和容量
**length() 元素的個(gè)數(shù)
**capacity 元素的理論值
F:獲取元素的位置
**indexOf
**lastIndexOf
G:截取
**substring(int start)
**substring(int start,int end)
H:反轉(zhuǎn)
**reverse
(5)字符串和StringBuffer的轉(zhuǎn)換
String-->StringBuffer通過(guò)構(gòu)造:
如:StringBuffer sb = new StringBuffer(String str)
StringBuffer--String通過(guò)toString方法
如:StringBuffer sb = new StringBuffer();
sb.toString();

3:StringBuilder
和StringBuffer的功能是一樣的奥务,但是有區(qū)別:
StringBuffer(JDK1.0)是線程安全的。
StringBuilder(JDK1.5)不保證線程安全袜硫。

一般來(lái)說(shuō)氯葬,我們寫(xiě)的程序都是單線程的,所以婉陷,用StringBuilder帚称,效率高。

JDK版本的升級(jí)原則:
A:提高效率
B:提高安全性
C:簡(jiǎn)化書(shū)寫(xiě)

4:基本數(shù)據(jù)類型的對(duì)象包裝類
(1)為了更方便的操作每個(gè)基本數(shù)據(jù)類型秽澳,java對(duì)其提供了很多的屬性和方法供我們使用闯睹。
(2)用途:
**將基本數(shù)據(jù)類型封裝成對(duì)象的好處在于可以在對(duì)象中定義更多的功能操作該數(shù)據(jù)。
**常用的操作之一:用于基本數(shù)據(jù)類型與字符串之間的轉(zhuǎn)換担神。
A:方便操作
B:用于和字符串進(jìn)行相互轉(zhuǎn)換
(3)基本數(shù)據(jù)類型和對(duì)象類型的對(duì)應(yīng)
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
(4)構(gòu)造方法

    字段摘要:
        static int MAX_VALUE 值為 2^31-1 的常量楼吃,它表示 int 類型能夠表示的最大值         
        static int MIN_VALUE  值為 -2^31 的常量,它表示 int 類型能夠表示的最小值
        static Class<Integer> TYPE 表示基本類型int的Class 實(shí)例
      
    Integer(int value) 構(gòu)造一個(gè)新分配的Integer對(duì)象,它表示指定的int值孩锡。
    Inreger(String s) 注意:s必須是純數(shù)字的字符串酷宵。否則會(huì)有異常NumberFormatException
                            
(5)幾個(gè)常用的方法
    Integer.toBinaryString();
        以二進(jìn)制(基數(shù) 2)無(wú)符號(hào)整數(shù)形式返回一個(gè)整數(shù)參數(shù)的字符串表示形式。
    Integer.toOctalString();
        以八進(jìn)制(基數(shù) 8)無(wú)符號(hào)整數(shù)形式返回一個(gè)整數(shù)參數(shù)的字符串表示形式躬窜。
    Integer.toHexString();
        以十六進(jìn)制(基數(shù) 16)無(wú)符號(hào)整數(shù)形式返回一個(gè)整數(shù)參數(shù)的字符串表示形式浇垦。
    static int Integer.parseInt(String s) 將字符串參數(shù)作為有符號(hào)的十進(jìn)制整數(shù)進(jìn)行解析,
        字符串必須是int型范圍內(nèi)的數(shù)字字符串
    static int Integer.parseInt(String s,int basic) 
        使用第二個(gè)參數(shù)指定的基數(shù),將字符串參數(shù)解析為有符號(hào)的整數(shù).
        字符串必須是int型范圍內(nèi)的數(shù)字字符串
    short shortValue() 以short類型返回該Integer的值。          
    int intValue() 以int類型返回該Integer的值荣挨。  
    static Integer valueOf(int num) 返回一個(gè)表示指定的 int 值的 Integer 實(shí)例男韧。
    static Integer valueOf(String s) 返回保存指定的String的值的Integer對(duì)象。           
            static Integer valueOf(String s, int radix) 
        返回一個(gè)Integer對(duì)象垦沉,該對(duì)象中保存了用第二個(gè)參數(shù)提供的基數(shù)進(jìn)行
        解析時(shí)從指定的String中提取的值煌抒。 

(6)類型轉(zhuǎn)換
    int -- Integer
        int num = 20;
        A:Integer i = new Integer(num);
        B:Integer i = Integer.valueOf(num);
    Integer -- int
        Integer i = new Integer(20);
        A:int num = i.intValue();
    
    int -- String
        int num = 20;
        A:String s = String.valueOf(num);
        B:String s = ""+num;
        C:String s = Integer.toString(num);
    String -- int
        String s = "20";
        A:int num = Integer.parseInt(s);
        B:Integer i = new Integer(s);或者Integer i = Integer.valueOf(s);
          int num = i.intValue();   

6仍劈、集合框架:
(1)為什么出現(xiàn)集合類厕倍?
面向?qū)ο髮?duì)事物的體現(xiàn)都是以對(duì)象的形式,為了方便對(duì)多個(gè)對(duì)象的操作贩疙,就對(duì)對(duì)象進(jìn)行存儲(chǔ)讹弯。
集合就是存儲(chǔ)對(duì)象最常用的一種方式.
(2)數(shù)組和集合都是容器,兩者有何不同这溅?
**數(shù)組長(zhǎng)度固定组民,而集合長(zhǎng)度是可變的
**數(shù)組值可以存儲(chǔ)對(duì)象,還可以存儲(chǔ)基本數(shù)據(jù)類型;而集合只能存儲(chǔ)對(duì)象
**數(shù)組存儲(chǔ)數(shù)據(jù)類型是固定的悲靴,而集合存儲(chǔ)的數(shù)據(jù)類型不固定
(3)集合類的特點(diǎn):
集合只能存儲(chǔ)對(duì)象
集合的長(zhǎng)度是可變的
集合可以存儲(chǔ)不同類型的對(duì)象
(4)集合類框架(重要3羰ぁ!癞尚!要分清幾種容器間的區(qū)別):
**Collection:頂層接口
|--->List:列表耸三,元素是有序的(元素帶角標(biāo)索引),可以有重復(fù)元素,可以有null元素浇揩。
|--->ArrayList(JDK1.2):底層的數(shù)據(jù)結(jié)構(gòu)是數(shù)組數(shù)據(jù)結(jié)構(gòu)仪壮,特點(diǎn)是查詢速度快(因?yàn)閹Ы菢?biāo)),
但是增刪速度稍慢,因?yàn)楫?dāng)元素多時(shí)胳徽,增刪一個(gè)元素則所有元素的角標(biāo)都得改變
線程不同步积锅。默認(rèn)長(zhǎng)度是10,當(dāng)超過(guò)長(zhǎng)度時(shí)养盗,按50%延長(zhǎng)集合長(zhǎng)度缚陷。
|--->LinkedList(JDK1.2):底層數(shù)據(jù)結(jié)構(gòu)式鏈表數(shù)據(jù)結(jié)構(gòu)(即后面一個(gè)元素記錄前一個(gè)),
特點(diǎn):查詢速度慢往核,因?yàn)槊總€(gè)元素只知道前面一個(gè)元素箫爷,但增刪速度快
因?yàn)樵卦俣啵鰟h一個(gè),只要讓其前后的元素重新相連即可
線程是不同步的蝶缀。
|--->Vector(JDK1.0):底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組數(shù)據(jù)結(jié)構(gòu).特點(diǎn)是查詢和增刪速度都很慢丹喻。
默認(rèn)長(zhǎng)度是10,當(dāng)超過(guò)長(zhǎng)度時(shí),按100%延長(zhǎng)集合長(zhǎng)度翁都。
線程同步碍论。
(Vector功能跟ArrayList功能一模一樣,已被ArrayList替代)

       **List使用注意柄慰!
        |--->ArrayList:
        (1)當(dāng)往ArrayList里面存入元素沒(méi)什么要求時(shí)鳍悠,即只要求有序就行時(shí);
           
        (2)當(dāng)往ArrayList里面存入元素要求不重復(fù)時(shí)坐搔,比如存入學(xué)生對(duì)象藏研,當(dāng)同名同姓時(shí)
           視為同一個(gè)人,則不往里面存儲(chǔ)概行。則定義學(xué)生對(duì)象時(shí)蠢挡,需復(fù)寫(xiě)equals方法
           public boolean equals(Object obj)
           {
            if(!(obj instanceof Student))
                return false;
            Student stu = (Student)obj;
            return this.name.equals(stu.name)&&this.age==stu.age;
           }
           則往ArrayList集合通過(guò)add存入學(xué)生對(duì)象時(shí),集合底層自己會(huì)調(diào)用學(xué)生類的equals方法凳忙,
           判斷重復(fù)學(xué)生則不存入业踏。
         注:對(duì)于List集合,無(wú)論是add涧卵、contains勤家、還是remove方法,判斷元素是否相同柳恐,
             都是通過(guò)復(fù)寫(xiě)equals方法來(lái)判斷伐脖!

        |--->LinkedList
        (1)LinkLedist的特有方法:
             boolean offerFirst(E e)  在此列表的開(kāi)頭插入指定的元素。
             boolean offerLast(E e) 在此列表末尾插入指定的元素乐设。
             E peekFirst() 獲取但不移除此列表的第一個(gè)元素讼庇;如果此列表為空,則返回 null伤提。
             E peekLast() 獲取但不移除此列表的最后一個(gè)元素巫俺;如果此列表為空,則返回 null肿男。
             E pollFirst() 獲取并移除此列表的第一個(gè)元素介汹;如果此列表為空,則返回 null舶沛。
             E pollLast() 獲取并移除此列表的最后一個(gè)元素嘹承;如果此列表為空,則返回 null如庭。
        (2)通過(guò)LinkLedist的特有方法叹卷,可以實(shí)現(xiàn)某些數(shù)據(jù)特殊方式的存取,比如堆棧和隊(duì)列。

            一般情況下骤竹,使用哪種List接口下的實(shí)現(xiàn)類呢帝牡?
            如果要求增刪快,考慮使用LinkedList
            如果要求查詢快蒙揣,考慮使用ArrayList
            如果要求線程安全靶溜,考慮使用Vector。



         |--->Set:集合懒震,元素是無(wú)序的(因?yàn)闆](méi)有索引)罩息,元素不可以重復(fù)「鋈牛可以有null元素瓷炮。
            |--->HashSet(JDK1.2):底層數(shù)據(jù)結(jié)構(gòu)是哈希表、存取速度快递宅、元素唯一娘香、線程不同步。
                 保證性元素唯一的原理:
                 先判斷元素的hashCode值是否相同恐锣,再判斷兩元素的equals方法是否為true
                 (往HashSet里面存的自定義元素要復(fù)寫(xiě)hashCode和equals方法茅主,
                 以保證元素的唯一性舞痰!)
            |--->TreeSet:底層數(shù)據(jù)結(jié)構(gòu)式二叉樹(shù)土榴。可以對(duì)Set集合中的元素進(jìn)行排序响牛。元素有序玷禽、線程不同步。
                 保證元素唯一性的依據(jù):compareTo方法return 0
                 TreeSet排序的第一種方式:讓元素自身具備比較性呀打,比如八種基本數(shù)據(jù)類型或則字符串矢赁,
                             實(shí)現(xiàn)Compareble接口,覆蓋compareTo方法,
                             此方式是元素的自然順序             
                 TreeSet排序的第一種方式:當(dāng)元素自身不具備比較性(比如存儲(chǔ)學(xué)生對(duì)象時(shí))或者具備的
                             比較性不是我們所需要的比較性時(shí)(比如想字符串的長(zhǎng)度排序),
                             此時(shí)就需要讓集合自身具備自定義的比較性贬丛。 
                             那如何讓集合自身具備比較性呢撩银?可在集合初始化時(shí),
                             就讓集合具備比較方式豺憔。即定義一個(gè)類额获,
                             實(shí)現(xiàn)Comparator接口,覆蓋compare方法恭应。

        **Set集合使用注意事項(xiàng):
        (1)HashSet:
              通過(guò)new的方式往HashSet里面存的元素的hashCode都不同抄邀,但通常我們定義對(duì)象,
              比如學(xué)生對(duì)象時(shí)昼榛,雖然是new的兩個(gè)學(xué)生對(duì)象境肾,但是當(dāng)他們name和age一樣時(shí),我們認(rèn)為是
              同一個(gè)對(duì)象,所以為了保證元素的唯一性奥喻,我們通常在往HashSet集合里面存儲(chǔ)元素時(shí)偶宫,
              在定義對(duì)象的類中通常復(fù)寫(xiě)hashCode和equals方法。
              public int hashCode()
              {
            return name.hashCode()+age*39;
              }
              public boolean equals(Object obj)
              {
            if(!(obj instanceof Student))
                return false;
            Student stu = (Student)obj;
            return this.name.equals(stu.name)&&this.age==stu.age;
              }

             HashSet是如何保證元素唯一性的呢环鲤?
              **如果兩元素的hashCode值不同读宙,則不會(huì)調(diào)用equals方法
              **如果兩元素的hashCode值相同,則繼續(xù)判斷equals是否返回true楔绞;
              **hashCode和equals方法雖然定義在自定義對(duì)象類里面结闸,但不是我們手動(dòng)調(diào)用
                而是往HashSet集合里面存儲(chǔ)元素的時(shí)候雷滚,集合底層自己調(diào)用hashCode和equals
            它自己拿對(duì)象去判斷透硝,自己判斷兩元素是否是同一個(gè)元素。

        (2)TreeSet:
             TreeSet要求往里面存的元素具備比較性抠忘,否則會(huì)報(bào)錯(cuò)蔫耽。
             TreeSet排序的第一種方式:讓元素自身具備比較性
              定義對(duì)象類结耀,實(shí)現(xiàn)Compareble接口,復(fù)寫(xiě)compareTo方法,此方式是元素的自然順序
              class Student implements Comparable
              {
                private String name;
                private int age;
                public Student(String name,int age)
                {
                    this.name=name;
                    this.age=age;
                }
                public String getName()
                {
                    return name;
                }
                public int getAge()
                {
                    return age;
                }
                public int compareTo(Object obj)
                {
                    if(!(obj instanceof Student))
                        throw new RuntimeException("不是學(xué)生對(duì)象匙铡!");
                    Student stu = (Student)obj;
                    int num = this.age-stu.age;
                    if(num==0)
                        return this.name.compareTo(stu.name);
                    return num;
                }
              }
            TreeSet排序的第一種方式:讓集合具備比較性
                 當(dāng)元素自身不具備比較性(比如存儲(chǔ)學(xué)生對(duì)象時(shí))或者具備的
                 比較性不是我們所需要的比較性時(shí)(比如想字符串的長(zhǎng)度排序),
                 此時(shí)就需要讓集合自身具備自定義的比較性图甜。 
                 那如何讓集合自身具備比較性呢?可在集合初始化時(shí)鳖眼,
                 就讓集合具備比較方式黑毅。即定義一個(gè)類,
                 實(shí)現(xiàn)Comparator接口钦讳,覆蓋compare方法矿瘦。
             class StringLengthComparator implements Comparator
             {
                public int compare(Object obj1,Object obj2)
                {
                    String s1 = (String)obj1;
                    String s2 = (String)obj2;
                    int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
                    if(num==0)
                        return s1.compareTo(s2);
                    return num;
                }
             }
             class TreeSetTest
             {
                public static void main(String[] args)
                {
                    TreeSet ts = new TreeSet(new StringLengthComparator());
                    ts.add("addfg");
                    ts.add("dfg");
                    ts.add("agtuug");
                    ts.add("vgjkg");
                    sop(ts);
                }
             }

             
                                
             基本數(shù)據(jù)類型或字符串對(duì)象均實(shí)現(xiàn)了Comparable接口,故同種類型基本數(shù)據(jù)間具備比較性愿卒,即自然順序缚去。

              
**Map:頂層接口,該集合存儲(chǔ)的是鍵值對(duì),而且鍵是唯一的,Map和Set很像,Set集合底層就是使用了Map集合。
    Map集合沒(méi)有迭代器琼开,要取出元素必須先將Map集合轉(zhuǎn)換成Set集合才能遍歷元素
   |--->HashTable(JDK1.0): 
    底層是哈希表數(shù)據(jù)結(jié)構(gòu)易结;
    不可以使用null鍵和null值;
    用作鍵的對(duì)象必須實(shí)現(xiàn)hashCode和equals方法來(lái)保證鍵的唯一性
    線程同步柜候,效率低
   |--->HashMap(JDK1.2):
    底層是哈希表數(shù)據(jù)結(jié)構(gòu)搞动;
    允許使用null鍵和null值;
    線程不同步改橘,效率高滋尉;
    保證元素唯一性的:
         原理:先判斷元素的hashCode值是否相同,再判斷兩元素的equals方法是否為true
         (往HashSet里面存的自定義元素要復(fù)寫(xiě)hashCode和equals方法飞主,
         以保證元素的唯一性狮惜!)
    class Student {
        private String name;
        private int age;
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        
        @Override
        public int hashCode(){
            return name.hashCode()+age*34;
        }
        @Override
        public boolean equals(Object obj){
            
            if(!(obj instanceof Student))
                return false;
            Student stu = (Student)obj;
            return this.name.equals(stu.name)&&this.age==stu.age;
        }
    public class HashMapDemo1 {
        public static void main(String[] args) {
            Map<Student , String> hmap = new HashMap<Student , String>();
            hmap.put(new Student("001",20), "beijing");
            hmap.put(new Student("002",25), "hebei");
            hmap.put(new Student("003",50), "hainan");
            hmap.put(new Student("001",20), "beijing");
            
            System.out.println(hmap.size());
            Set<Student> keySet = hmap.keySet();
            Iterator<Student> it = keySet.iterator();
            while(it.hasNext()){
                Student stu = it.next();
                String addr = hmap.get(stu);
                System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);
            }   
        }   
    }           
   |--->TreeMap(JDK1.0):
    底層是二叉樹(shù)結(jié)構(gòu)高诺;
    允許使用null鍵和null值;
    線程不同步碾篡;
    可以給Map集合中的鍵進(jìn)行排序.
    TreeMap排序的第一種方式:讓元素自身具備比較性虱而,比如八種基本數(shù)據(jù)類型或則字符串,
             實(shí)現(xiàn)Compareble接口,覆蓋compareTo方法开泽,
             此方式是元素的自然順序             
    TreeMap排序的第一種方式:當(dāng)元素自身不具備比較性(比如存儲(chǔ)學(xué)生對(duì)象時(shí))或者具備的
             比較性不是我們所需要的比較性時(shí)(比如想字符串的長(zhǎng)度排序),
             此時(shí)就需要讓集合自身具備自定義的比較性牡拇。 
             那如何讓集合自身具備比較性呢?可在集合初始化時(shí)穆律,
             就讓集合具備比較方式惠呼。即定義一個(gè)類,
             實(shí)現(xiàn)Comparator接口峦耘,覆蓋compare方法剔蹋。
    class Student implements Comparable<Student>{
        private String name;
        private int age;
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public int compareTo(Student stu) {
            int num = new   Integer(this.age).compareTo(new Integer(stu.age));
            if(num==0)
                return this.name.compareTo(stu.name);
            return num;
        }           
    }

    public class HashMapDemo1 {
        public static void main(String[] args) {
                        
            Map<Student , String> tmap = new TreeMap<Student , String>();
            tmap.put(new Student("001",20), "beijing");
            tmap.put(new Student("002",25), "hebei");
            tmap.put(new Student("003",50), "hainan");
            tmap.put(new Student("001",20), "beijing");
            
            System.out.println(tmap.size());
            Set<Student> keySet1 = tmap.keySet();
            Iterator<Student> it1 = keySet1.iterator();
            while(it1.hasNext()){
                Student stu = it1.next();
                String addr = tmap.get(stu);
                System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);      
            }
        }
    }


**Iterator:對(duì)collection進(jìn)行迭代的迭代器.迭代器取代了Enumeration。
    迭代器和枚舉的區(qū)別:
    迭代器允許調(diào)用者利用定義良好的語(yǔ)義在迭代期間從迭代器所指向的collection移除元素
    方法名稱得到了改進(jìn)辅髓,簡(jiǎn)化書(shū)寫(xiě) 
**LisIterator:系列表迭代器泣崩,允許程序員按任一方向遍歷列表、迭代期間修改列表        
**Comparable:此接口強(qiáng)行對(duì)實(shí)現(xiàn)它的每個(gè)類的對(duì)象進(jìn)行整體自然排序洛口。使元素具備比較性
**Comparator:強(qiáng)行對(duì)某個(gè)對(duì)象collection進(jìn)行整體排序的比較函數(shù)矫付,使集合具備比較性
**Collections:此類完全由在 collection 上進(jìn)行操作或返回 collection 的靜態(tài)方法組成。
**Arrays:此類包含用來(lái)操作數(shù)組(比如排序和搜索)的各種靜態(tài)方法

7第焰、集合類各容器方法:
**接口Collection方法摘要(沒(méi)有構(gòu)造方法)
a)添加:
i. boolean add(E e)
j. boolean addAll(Collection c)
b)刪除:
i. void clear():清空容器
j. boolean remove(Objec object):
k. boolean removeAll(Collection c):
c)判斷:
i. boolean contains(Object object):判斷是否包含此元素
j. boolean containsAll(Collection c):判斷是否包含一堆元素
k. boolean equals(Object object):比較此collection與指定對(duì)象是否相等
m. boolean isEmpty():判斷是否集合為空
d)獲嚷蛴拧:
h. Iterator iterator():取出
i. int hashCode():返回此collection的哈希值
j. int size():返回此collection中元素的個(gè)數(shù)
k. boolean retainAll(Collection c):取交集
m. Object toArray():返回此collection中所有元素的數(shù)組
n. T[] toArray(T[] a):返回包含此collection中所有元素的數(shù)值。
*****List集合子類及其方法
(1)List接口是Collection接口的一個(gè)子接口樟遣。
(2)List接口中的元素有如下特點(diǎn)(對(duì)角標(biāo)的操作都是特有方法而叼,因?yàn)橛行?:
A:元素有序(存儲(chǔ)順序和取出順序一致)
B:元素可以重復(fù)
(3)List接口中的特有方法
A:add(int index,Object obj):在指定位置加入元素
B:remove(int index):移除指定位置的元素
C:set(int index,Object obj):修改指定位置的元素
D:get(int index):獲取指定位置的元素
E:indexOf(Object obj):獲取指定元素的位置
F:subList(int start,int end):從一個(gè)大的List中截取一個(gè)小的List
G:listIterator():返回一個(gè)List接口特有的迭代器
(1)、ArrayList:
|--->構(gòu)造方法摘要:(少用豹悬,不是重點(diǎn))
ArrayList():構(gòu)造一個(gè)初始容量為 10 的空列表。
ArrayList(Collection<? extends E> c): 構(gòu)造一個(gè)包含指定 collection 的元素的列表液荸,
ArrayList(int initialCapacity): 構(gòu)造一個(gè)具有指定初始容量的空列表瞻佛。
|--->方法摘要:
|--->添加:
boolean add(E e): 將指定的元素添加到此列表的尾部。
void add(int index, E element): 將指定的元素插入此列表中的指定位置娇钱。
boolean addAll(Collection<? extends E> c):按照指定 collection 的迭代器所返回的元素順序伤柄,
將該 collection 中的所有元素添加到此列表的尾部
boolean addAll(int index, Collection<? extends E> c): 從指定的位置開(kāi)始,將指定 collection
中的所有元素插入到此列表中文搂。
|--->刪除:
void clear(): 移除此列表中的所有元素适刀。
E remove(int index): 移除此列表中指定位置上的元素。
boolean remove(Object o): 移除此列表中首次出現(xiàn)的指定元素(如果存在)煤蹭。
protected void removeRange(int fromIndex, int toIndex):
移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之間的所有元素笔喉。
boolean removeAll(Collection<?> c): 從列表中移除指定 collection 中包含的其所有元素
|--->獲热∈印:
E get(int index): 返回此列表中指定位置上的元素。
int indexOf(Object o): 返回此列表中首次出現(xiàn)的指定元素的索引常挚,或如果此列表不包含元素作谭,則返回 -1。
int lastIndexOf(Object o) 返回此列表中最后一次出現(xiàn)的指定元素的索引奄毡,或如果此列表不包含索引折欠,則返回 -1。
public List<E> subList(int fromIndex,int toIndex): 返回列表中指定的 fromIndex(包括 ) 和 toIndex(不包括)之間的部分視圖吼过。
Iterator<E> iterator(): 返回按適當(dāng)順序在列表的元素上進(jìn)行迭代的迭代器锐秦。
ListIterator<E> listIterator(int index):返回列表中元素的列表迭代器(按適當(dāng)順序),從列表的指定位置開(kāi)始。
|--->修改:(特有方法5脸馈农猬!)
E set(int index, E element): 用指定的元素替代此列表中指定位置上的元素。
(2)LinkedList:
|--->構(gòu)造方法摘要:
LinkedList(): 構(gòu)造一個(gè)空列表售淡。
LinkedList(Collection<? extends E> c): 構(gòu)造一個(gè)包含指定 collection 中的元素的列表斤葱,
這些元素按其 collection 的迭代器返回的順序排列。
|--->方法摘要:(特有的)
|--->添加
void addFirst(E e): 將指定元素插入此列表的開(kāi)頭揖闸。
void addLast(E e): 將指定元素添加到此列表的結(jié)尾揍堕。
|--->獲取元素,但不刪除元素
E get(int index): 返回此列表中指定位置處的元素汤纸。
E getFirst(): 返回此列表的第一個(gè)元素衩茸。
E getLast(): 返回此列表的最后一個(gè)元素。
|--->獲取元素且刪除元素
E remove(): 獲取并移除此列表的頭(第一個(gè)元素)贮泞。
E remove(int index): 移除此列表中指定位置處的元素楞慈。
boolean remove(Object o): 從此列表中移除首次出現(xiàn)的指定元素(如果存在)。
E removeFirst(): 移除并返回此列表的第一個(gè)元素啃擦。
E removeLast(): 移除并返回此列表的最后一個(gè)元素囊蓝。
|--->修改
E set(int index, E element) 將此列表中指定位置的元素替換為指定的元素。
(3)Vector
|--->構(gòu)造方法摘要:
Vector(): 構(gòu)造一個(gè)空向量令蛉,使其內(nèi)部數(shù)據(jù)數(shù)組的大小為 10聚霜,其標(biāo)準(zhǔn)容量增量為零。
Vector(Collection<? extends E> c): 構(gòu)造一個(gè)包含指定 collection 中的元素的向量珠叔,
這些元素按其 collection 的迭代器返回元素的順序排列蝎宇。
|--->方法摘要:
|--->添加:
boolean add(E e): 將指定元素添加到此向量的末尾。
void add(int index, E element): 在此向量的指定位置插入指定的元素祷安。
boolean addAll(Collection<? extends E> c):
將指定 Collection 中的所有元素添加到此向量的末尾姥芥,
按照指定 collection 的迭代器所返回的順序添加這些元素。
boolean addAll(int index, Collection<? extends E> c): 在指定位置將指定 Collection 中的所有元素插入到此向量中汇鞭。
|--->獲取:
Enumeration<E> elements(): 返回此向量的組件的枚舉凉唐。
Vector特有的取出方式:
枚舉和迭代器很像庸追,其實(shí)枚舉和迭代器是一樣的,只是因?yàn)槊杜e的名稱和方法的名稱
名字都過(guò)長(zhǎng)熊榛,所以枚舉被迭代器取代了锚国。
|--->枚舉Enumeration的方法摘要:
boolean hasMoreElements(): 測(cè)試此枚舉是否包含更多的元素。
E nextElement(): 如果此枚舉對(duì)象至少還有一個(gè)可提供的元素玄坦,
則返回此枚舉的下一個(gè)元素血筑。
*****Set集合子類及其方法
(1)HashSet:它不保證set的迭代順序;特別是它不保證該順序恒久不變.此類允許使用null元素。
|--->構(gòu)造方法:
HashSet() 構(gòu)造一個(gè)新的空 set煎楣,其底層 HashMap 實(shí)例的默認(rèn)初始容量是 16豺总,加載因子是 0.75。
HashSet(Collection<? extends E> c) 構(gòu)造一個(gè)包含指定 collection 中的元素的新 set择懂。
|--->方法摘要:
boolean add(E e) 如果此 set 中尚未包含指定元素喻喳,則添加指定元素。
void clear() 從此 set 中移除所有元素困曙。
Object clone() 返回此 HashSet 實(shí)例的淺表副本:并沒(méi)有復(fù)制這些元素本身表伦。
boolean contains(Object o) 如果此 set 包含指定元素,則返回 true慷丽。
boolean isEmpty() 如果此 set 不包含任何元素蹦哼,則返回 true。
Iterator<E> iterator() 返回對(duì)此 set 中元素進(jìn)行迭代的迭代器要糊。
boolean remove(Object o) 如果指定元素存在于此 set 中纲熏,則將其移除。
int size() 返回此 set 中的元素的數(shù)量(set 的容量)锄俄。
(2)TreeSet:使用元素的自然順序?qū)υ剡M(jìn)行排序局劲,或者根據(jù)創(chuàng)建 set 時(shí)提供的 Comparator 進(jìn)行排序.
|--->構(gòu)造方法:
TreeSet() 構(gòu)造一個(gè)新的空 set,該set根據(jù)其元素的自然順序進(jìn)行排序奶赠。
TreeSet(Collection<? extends E> c)
構(gòu)造一個(gè)包含指定 collection 元素的新 TreeSet鱼填,它按照其元素的自然順序進(jìn)行排序。
TreeSet(Comparator<? super E> comparator) 構(gòu)造一個(gè)新的空 TreeSet车柠,它根據(jù)指定比較器進(jìn)行排序剔氏。
|--->方法摘要:
添加:
boolean add(E e) 將指定的元素添加到此 set(如果該元素尚未存在于 set 中)。
boolean addAll(Collection<? extends E> c) 將指定 collection 中的所有元素添加到此 set 中竹祷。
刪除:
void clear() 移除此 set 中的所有元素。
boolean remove(Object o) 將指定的元素從 set 中移除(如果該元素存在于此 set 中)羊苟。
E pollFirst() 獲取并移除第一個(gè)(最低)元素塑陵;如果此 set 為空,則返回 null蜡励。
E pollLast() 獲取并移除最后一個(gè)(最高)元素令花;如果此 set 為空阻桅,則返回 null。
獲燃娑肌:
Iterator<E> iterator() 返回在此 set 中的元素上按升序進(jìn)行迭代的迭代器嫂沉。
E first() 返回此 set 中當(dāng)前第一個(gè)(最低)元素。
E last() 返回此 set 中當(dāng)前最后一個(gè)(最高)元素扮碧。
int size() 返回 set 中的元素?cái)?shù)(set 的容量)趟章。
判斷:
boolean isEmpty() 如果此 set 不包含任何元素,則返回 true慎王。
boolean contains(Object o) 如果此 set 包含指定的元素蚓土,則返回 true。
**Map:將鍵映射到值的對(duì)象赖淤。Map集合沒(méi)有迭代器蜀漆!Map集合特點(diǎn):該集合存儲(chǔ)鍵值對(duì)。而且鍵是唯一的咱旱。
|--->方法摘要:
|--->添加:
V put(K key, V value) 將指定的值與此映射中的指定鍵關(guān)聯(lián)(可選操作)确丢。
void putAll(Map<? extends K,? extends V> m) 從指定映射中將所有映射關(guān)系復(fù)制到此映射中
|--->刪除:
void clear() 從此映射中移除所有映射關(guān)系(可選操作)。
V remove(Object key) 如果存在一個(gè)鍵的映射關(guān)系吐限,則將其從此映射中移除(可選操作)鲜侥。
|--->判斷
boolean containsKey(Object key) 如果此映射包含指定鍵的映射關(guān)系,則返回 true毯盈。
boolean containsValue(Object value) 如果此映射將一個(gè)或多個(gè)鍵映射到指定值剃毒,則返回 true。
boolean isEmpty() 如果此映射未包含鍵-值映射關(guān)系,則返回 true。
|--->獲取
int size() 返回此映射中的鍵-值映射關(guān)系數(shù)垮兑。
Collection<V> values() 返回此映射中包含的值的 Collection 視圖岂丘。

  重點(diǎn):Map集合沒(méi)有迭代器,以下是Map的兩種取出方式:
  第一種:Set<K> keySet()
    返回此映射中包含的鍵的Set視圖琴庵,將Map集合中所有的鍵存入Set集合,然后再通過(guò)Set集合的
    迭代器取出所有的鍵,再根據(jù)get方法獲取每個(gè)鍵的值轰豆;
  第二種:Set<Map.Entry<K,V>> entrySet() 
    返回此映射中包含的映射關(guān)系的Set視圖,將Map集合中的映射關(guān)系存入到Set集合中齿诞,
    這個(gè)映射關(guān)系的數(shù)據(jù)類型是Map.entry,再通過(guò)Map.Entry類的方法再要取出關(guān)系里面的鍵和值
    Map.Entry的方法摘要:
        boolean equals(Object o)  比較指定對(duì)象與此項(xiàng)的相等性酸休。              
        K getKey()  返回與此項(xiàng)對(duì)應(yīng)的鍵。            
        V getValue() 返回與此項(xiàng)對(duì)應(yīng)的值祷杈。            
        int hashCode() 返回此映射項(xiàng)的哈希碼值斑司。
        V setValue(V value) 用指定的值替換與此項(xiàng)對(duì)應(yīng)的值(特有!5宿刮!)互站。

8、Map集合和Collection集合的區(qū)別僵缺?
1胡桃,
Map中一次存儲(chǔ)是鍵值對(duì)。
Collection中一次存儲(chǔ)是單個(gè)元素磕潮。
2翠胰,
Map的存儲(chǔ)使用的put方法。
Collection存儲(chǔ)使用的是add方法揉抵。
3亡容,
Map集合沒(méi)有迭代器,Map的取出冤今,是將Map轉(zhuǎn)成Set闺兢,在使用迭代器取出。
Collection取出戏罢,使用就是迭代器屋谭。
4,
如果對(duì)象很多龟糕,必須使用集合存儲(chǔ)桐磁。
如果元素存在著映射關(guān)系,可以優(yōu)先考慮使用Map存儲(chǔ)或者用數(shù)組讲岁,
如果沒(méi)有映射關(guān)系我擂,可以使用Collection存儲(chǔ)。
8缓艳、迭代器:Iterator(Map集合沒(méi)有迭代器)
(1)迭代器就是取出集合元素的方式
(2)迭代器的作用
因?yàn)槊總€(gè)集合中元素的取出方式都不一樣校摩,于是就把元素的取出方式進(jìn)行抽取,并定義在集合內(nèi)部阶淘,
這樣取出方式就可以直接訪問(wèn)集合內(nèi)部的元素衙吩;
而每個(gè)容器的數(shù)據(jù)結(jié)構(gòu)不同,所以取出動(dòng)作的細(xì)節(jié)也不一樣溪窒,但是有共性內(nèi)容:判斷和取出坤塞。
那么就將共性內(nèi)容進(jìn)行抽取,從而形成了接口Iterater
(3)獲取迭代器的方法:
Iterator<E> iterator() 返回在此 collection 的元素上進(jìn)行迭代的迭代器澈蚌。
Iterator<E> iterator() 返回在此 set 中的元素上進(jìn)行迭代的迭代器摹芙。
(3)迭代器方法:
boolean hasNext() 如果仍有元素可以迭代,則返回 true。
E next() 返回迭代的下一個(gè)元素宛瞄。
void remove() 從迭代器指向的collection中移除迭代器返回的最后一個(gè)元素(可選操作)瘫辩。
9、列表迭代器:ListIterator
(1)List集合特有的迭代器ListIterator是Iterator的子接口坛悉,在迭代時(shí)伐厌,不可以通過(guò)集合對(duì)象的
方法操作集合中的元素,因?yàn)闀?huì)發(fā)生ConcurrentModificationException(當(dāng)方法檢測(cè)到對(duì)象的并發(fā)修改裸影,
但不允許這種修改時(shí)挣轨,拋出此異常)
(2)Iterator方法有限,只能對(duì)元素進(jìn)行判斷轩猩、取出和刪除的操作
ListIterator可以對(duì)元素進(jìn)行添加和修改動(dòng)作等卷扮。
(3)獲取列表迭代器方法:
ListIterator<E> listIterator() 返回此列表元素的列表迭代器(按適當(dāng)順序)。
ListIterator<E> listIterator(int index)
返回此列表中的元素的列表迭代器(按適當(dāng)順序)均践,從列表中指定位置開(kāi)始晤锹。
(4)列表迭代器方法:
void add(E e) 將指定的元素插入列表(可選操作)。
boolean hasPrevious() 如果以逆向遍歷列表彤委,列表迭代器有多個(gè)元素鞭铆,則返回 true。
int nextIndex() 返回對(duì) next 的后續(xù)調(diào)用所返回元素的索引焦影。
E previous() 返回列表中的前一個(gè)元素车遂。
int previousIndex() 返回對(duì) previous 的后續(xù)調(diào)用所返回元素的索引。
void set(E e) 用指定元素替換 next 或 previous 返回的最后一個(gè)元素(可選操作)斯辰。
10舶担、堆棧和隊(duì)列
堆棧:先進(jìn)后出,比如杯子里的水
隊(duì)列:先進(jìn)先出彬呻,比如水管的水
11衣陶、集合類各種容器的使用注意細(xì)節(jié):
(1)迭代器:
**迭代器的next方法是自動(dòng)向下取元素,要避免出現(xiàn)NoSuchElementException闸氮。
也就是在迭代循環(huán)中調(diào)用一次next方法一次就要hasNext判斷一次剪况,比如語(yǔ)句
sop(it.next()+"..."+it.next())會(huì)發(fā)生上述異常。
**迭代器的next方法返回值類型是Object湖苞,所以要記得類型轉(zhuǎn)換,應(yīng)用泛型后就不用強(qiáng)轉(zhuǎn)
(2)List集合:
**List集合里面的元素因?yàn)槭菐Ы菢?biāo)拯欧,所以List集合里面的元素都是有序的,
另外List集合可以包含重復(fù)元素财骨,也可以包含null镐作。
**List集合有迭代器Iterator,還有一個(gè)特有迭代器列表ListIterator
**List集合中判斷元素是否相同都是用equals方法隆箩,無(wú)論contains该贾、remove都依賴equals方法
比如往ArrayList集合里面存放學(xué)生,同名同年齡視為同一個(gè)人捌臊,此時(shí)就需要在學(xué)生類復(fù)寫(xiě)Object類
里面的equals方法(非常重要Q畹啊!!要注意3蚜Α曙寡!)
(3)Set集合:
**Set接口里面存放的是元素是無(wú)序的,不可以有重復(fù)元素寇荧,可以包含null
**Set集合只有一種取出方式举庶,就是迭代器Iterator
**Set集合功能和Collection是一致的,沒(méi)有特殊方法
|--->HashSet:
**集合里面存放的元素是無(wú)序的揩抡,唯一的
**底層數(shù)據(jù)結(jié)構(gòu)是哈希表户侥,哈希表結(jié)構(gòu)的數(shù)據(jù)都是無(wú)序的,哈希表結(jié)構(gòu)的操作效率都高效
**線程不同步
**保證元素唯一性的原理是:通過(guò)復(fù)寫(xiě)hashCode和equals方法
****如果兩元素的hashCode值相同峦嗤,則繼續(xù)判斷兩元素equals是否為真
****如果兩元素的hashCode值不同蕊唐,則不會(huì)調(diào)用equals方法。
**當(dāng)我們往HashSet集合存放自定義的元素時(shí)(比如學(xué)生對(duì)象)烁设,通常都要復(fù)寫(xiě)hashCode和equals方法替梨,
而且hashCode和equals方法不通過(guò)我們調(diào)用,HashSet集合底層內(nèi)部自己調(diào)用署尤,自己拿元素去比較
|--->TreeSet
**TreeSet集合可以對(duì)存放的元素進(jìn)行排序耙替,彌補(bǔ)了Set集合元素?zé)o序的缺點(diǎn),且元素是唯一的
**底層數(shù)據(jù)結(jié)構(gòu)是二叉樹(shù)曹体,二叉樹(shù)結(jié)構(gòu)都是有序的
**線程不同步
**TreeSet集合要求往集合里存放的元素自身具備比較性俗扇,否則會(huì)報(bào)錯(cuò)
**TreeSet集合保證元素唯一性的依據(jù)是:通過(guò)compareTo或者compare方法中的來(lái)保證元素的唯一性。
TreeSet排序的第一種方式:讓元素自身具備比較性箕别,
定義元素類實(shí)現(xiàn)Compareble接口铜幽,覆蓋compare方法,
此方式是元素的自然順序串稀。
TreeSet排序的第二種方式:讓集合具備比較性
當(dāng)元素自身不具備比較性或者具備的比較性不是
我們所需要的比較性時(shí)除抛,此時(shí)就需要讓集合具備自定義的比較性。
那如何讓集合自身具備比較性呢母截?
可在集合初始化時(shí)到忽,就讓集合具備比較方式。
即定義一個(gè)類清寇,實(shí)現(xiàn)Comparator接口喘漏,覆蓋compare方法。
注:
**判斷元素唯一時(shí)华烟,當(dāng)主要條件一樣時(shí)翩迈,判斷次要條件
**兩種排序方式都在時(shí),以比較器為主?埂8核恰堤魁!
(4)Map集合:
|--Hashtable
底層是哈希表結(jié)構(gòu)
線程安全的,并且鍵和值不能為null返十。
|--HashMap
底層是哈希表結(jié)構(gòu)
線程不安全的妥泉,鍵和值可以為null。
|--LinkedHashMap
底層是鏈表和哈希表
線程不安全
|--TreeMap
底層是二叉樹(shù)
線程不安全的
12吧慢、如果你想將一組對(duì)象按一定順序存取涛漂,在不考慮并發(fā)訪問(wèn)的情況下會(huì)使用____C_____ ,
反之則會(huì)使用____A_____;如果你想存儲(chǔ)一組無(wú)序但唯一的對(duì)象检诗,你會(huì)使用___B______ ;
如果你想按關(guān)鍵字對(duì)對(duì)象進(jìn)行存取,在不考慮并發(fā)訪問(wèn)的情況下會(huì)使用___D______ ,反之則會(huì)使用_____E____瓢剿。
A. Vector
B. HashSet
C. ArrayList
D. HashMap

E. Hashtable
13逢慌、泛型:
(1)為什么會(huì)出現(xiàn)泛型?
因?yàn)榧洗娣诺臄?shù)據(jù)類型不固定间狂,故往集合里面存放元素時(shí)攻泼,存在安全隱患,
如果在定義集合時(shí)鉴象,可以想定義數(shù)組一樣指定數(shù)據(jù)類型忙菠,那么就可以解決該類安全問(wèn)題。
JDK1.5后出現(xiàn)了泛型纺弊,用于解決集合框架的安全問(wèn)題牛欢。
泛型是一個(gè)類型安全機(jī)制。
(2)泛型定義格式:通過(guò)<>來(lái)定義要操作的引用數(shù)據(jù)類型
ArrayList<String> al = new ArrayList<String>;
(3)泛型的好處:
**將運(yùn)行時(shí)期出現(xiàn)的ClassCastException(類型轉(zhuǎn)換異常)問(wèn)題轉(zhuǎn)移到編譯時(shí)期淆游;
**避免了強(qiáng)制轉(zhuǎn)換的麻煩
(4)什么時(shí)候定義泛型傍睹?
泛型在集合框架中很常見(jiàn),只要見(jiàn)到<>就要定義泛型犹菱。其實(shí)<>就是用來(lái)接收類型的拾稳。
當(dāng)使用集合時(shí),將集合中要存儲(chǔ)的數(shù)據(jù)類型作為參數(shù)傳遞到<>中即可
(5)泛型的形式
**泛型類:即自定義泛型類
A:當(dāng)類中要操作的引用數(shù)據(jù)類型不確定時(shí)腊脱,早起定義Object來(lái)完成擴(kuò)展访得,現(xiàn)在定義泛型來(lái)完成
B:局限性:泛型類定義的泛型,在整個(gè)類中有效陕凹,如果該泛型類的方法被調(diào)用悍抑,
當(dāng)泛型類的對(duì)象明確要操作的類型后,所有要操作的類型就被固定捆姜。
**泛型方法:泛型放在返回值前面传趾,修飾符的后面
A:為了避免泛型類的局限性,讓不同方法可以操作不同的類型泥技,而且類型還不確定浆兰,
則可以將泛型定義在方法上
B:特殊之處:靜態(tài)方法不可以反回類上定義的泛型
如果靜態(tài)方法操作的應(yīng)用數(shù)據(jù)類型不確定磕仅,可以講泛型定義在靜態(tài)方法上
**泛型接口:
當(dāng)泛型定義在接口上時(shí),則子類中要指定實(shí)現(xiàn)接口類型簸呈,同時(shí)還可以子類也可以定義為泛型類
(6)泛型的高級(jí)應(yīng)用:榕订?通配符
**當(dāng)指定兩種泛型的集合,則迭代時(shí)也要定義兩種泛型的迭代器蜕便,麻煩劫恒,此時(shí)可通過(guò)將迭代器的泛型
改為?,如Iterator<?> it=al.iterator();
**兩種泛型限定
向上限定: ? extends E ;E可以接收E類型或者E的子類
向下限定: ? super E ;E可以接收E類型或者E的父類
14胖齐、高級(jí)for循環(huán)
(1)JDK1.5新特性享甸,代替迭代器使用時(shí)的不爽,簡(jiǎn)化書(shū)寫(xiě)憔辫,底層原理是迭代器凡是支持迭代器的都支持高級(jí)for循環(huán)
高級(jí)for循環(huán),只用于集合和數(shù)組的遍歷仿荆,集合只能用Collection不能用Map集合
只能把Map集合轉(zhuǎn)化成Set集合贰您,才能用for循環(huán)。
(2)格式
for(數(shù)據(jù)類型 變量名:被遍歷的集合(Collection)或者數(shù)組)
{

    }
    (3)局限性:
    必須要有遍歷的目標(biāo)
    對(duì)集合或者數(shù)組進(jìn)行遍歷時(shí)拢操,只能獲取集合元素锦亦,不能對(duì)集合元素進(jìn)行操作
    迭代器除了遍歷,還可以進(jìn)行remove操作集合中的元素
    列表迭代器還可以在遍歷過(guò)程中進(jìn)行增刪改查的操作
(4)傳統(tǒng)for循環(huán)和高級(jí)for循環(huán)的區(qū)別
    高級(jí)for循環(huán)有一個(gè)局限性令境,就是必須要有遍歷的目標(biāo)(集合或者數(shù)組)
    遍歷數(shù)組時(shí)建議使用傳統(tǒng)for循環(huán)杠园,因?yàn)榭梢远x角標(biāo),比如打印100次helloworld時(shí)用傳統(tǒng)for循環(huán)方便

15展父、可變參數(shù)
(1)數(shù)組的可變參數(shù)
格式:
int... arr
(3)方法的可變參數(shù)
格式:
public static void show(String str返劲,int... arr)
{

        }
    注意:可變參數(shù)一定要放在參數(shù)列表的最后面

16、靜態(tài)導(dǎo)入:
*import static java.util.Arrays. 導(dǎo)入的是Arrays這個(gè)類中所有的靜態(tài)方法
**當(dāng)類名重名時(shí)栖茉,需要制定具體的報(bào)名
**當(dāng)方法重名時(shí)篮绿,需要制定具體所屬的對(duì)象或者類
17、Collections類:
(1)此類完全由在 collection 上進(jìn)行操作或返回 collection 的靜態(tài)方法組成吕漂。
(2)靜態(tài)方法摘要:
static <T> boolean addAll(Collection<? super T> c, T... elements)
將所有指定元素添加到指定 collection 中亲配。
static <T> void fill(List<? super T> list, T obj)
使用指定元素替換指定列表中的所有元素。
static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)
使用另一個(gè)值替換列表中出現(xiàn)的所有某一指定值惶凝。
static void reverse(List<?> list)
反轉(zhuǎn)指定列表中元素的順序吼虎。
static <T> Comparator<T> reverseOrder()
返回一個(gè)比較器,它強(qiáng)行逆轉(zhuǎn)實(shí)現(xiàn)了 Comparable 接口的對(duì)象 collection 的自然順序
static <T> Comparator<T> reverseOrder(Comparator<T> cmp)
返回一個(gè)比較器苍鲜,它強(qiáng)行逆轉(zhuǎn)指定比較器的順序思灰。
(3)Collections類特牛的方法:
集合有一個(gè)共同的缺點(diǎn),那就是線程不安全混滔,被多線程操作時(shí)洒疚,容易出現(xiàn)問(wèn)題歹颓,雖然可以自己加鎖
但是麻煩。Collections提供特牛的方法油湖,就是給它一個(gè)不同步的集合巍扛,它返回一個(gè)同步的安全的集合

    static <T> Collection<T> synchronizedCollection(Collection<T> c) 
        返回指定 collection 支持的同步(線程安全的)collection。 
    static <T> List<T>  synchronizedList(List<T> list) 
        返回指定列表支持的同步(線程安全的)列表乏德。 
    static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) 
        返回由指定映射支持的同步(線程安全的)映射撤奸。 
    static <T> Set<T> synchronizedSet(Set<T> s) 
        返回指定 set 支持的同步(線程安全的)set。 
    static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
        返回指定有序映射支持的同步(線程安全的)有序映射喊括。 
    static <T> SortedSet<T>  synchronizedSortedSet(SortedSet<T> s)
        返回指定有序 set 支持的同步(線程安全的)有序 set胧瓜。 

18、Arrays類:
此類包含用來(lái)操作數(shù)組(比如排序和搜索)的各種方法瘾晃。里面都是靜態(tài)方法贷痪。
如果指定數(shù)組引用為 null,則此類中的方法都會(huì)拋出 NullPointerException蹦误。
(1)靜態(tài)方法摘要:
static <T> List<T> asList(T... a)
返回一個(gè)受指定數(shù)組支持的固定大小的列表。
注意:
A:該方法將一個(gè)數(shù)組變成集合后肉津,不可以使用集合的增刪方法强胰,因?yàn)閿?shù)組的長(zhǎng)度是固定的!
如果增刪妹沙,則發(fā)生UnsupportedOprationException(不支持操作異常)
B:如果數(shù)組中的元素都是基本數(shù)據(jù)類型偶洋,則該數(shù)組變成集合時(shí),會(huì)將該數(shù)組作為集合的一個(gè)
元素出入集合
C:如果數(shù)組中的元素都是對(duì)象距糖,如String玄窝,那么數(shù)組變成集合后,數(shù)組中的元素就直接轉(zhuǎn)成
集合中的元素
19悍引、數(shù)組變集合以及集合變數(shù)組的對(duì)比:
(1)數(shù)組變集合:
方法:static <T> List<T> asList(T... a) 返回一個(gè)受指定數(shù)組支持的固定大小的列表恩脂。
好處:可以使用集合的思想和方法操作數(shù)組中的元素,數(shù)組是一個(gè)對(duì)象趣斤,但是數(shù)組中的功能很少
(2)集合變數(shù)組:
方法:Collction中的toArray方法
好處:可以限定對(duì)集合元素的操作俩块,防止對(duì)集合的元素進(jìn)行增刪,因?yàn)閿?shù)組長(zhǎng)度是固定的浓领。

20玉凯、Collections類和Arrays類的使用。(重點(diǎn))
A:Collections
排序
二分查找
發(fā)轉(zhuǎn)
B:Arrays
把數(shù)組變成字符串輸出
排序
二分查找
21联贩、System:
(1)描述系統(tǒng)信息的類
(2)該類沒(méi)有構(gòu)造方法漫仆,該類的方法和屬性都是靜態(tài)的
(3)字段摘要:
static InputStream in “標(biāo)準(zhǔn)”輸入流。
static PrintStream out “標(biāo)準(zhǔn)”輸出流泪幌。
(4)方法摘要:
static void exit(int status) 終止當(dāng)前正在運(yùn)行的 Java 虛擬機(jī)盲厌。
static void gc() 運(yùn)行垃圾回收器署照。
static Properties getProperties() 確定當(dāng)前的系統(tǒng)屬性
static String getProperty(String key) 獲取指定鍵指示的系統(tǒng)屬性。
static String getProperty(String key, String def) 獲取用指定鍵描述的系統(tǒng)屬性狸眼。
static void setIn(InputStream in) 重新分配“標(biāo)準(zhǔn)”輸入流藤树。
static void setOut(PrintStream out) 重新分配“標(biāo)準(zhǔn)”輸出流。
static void setProperties(Properties props) 將系統(tǒng)屬性設(shè)置為 Properties 參數(shù)拓萌。
static String setProperty(String key, String value) 設(shè)置指定鍵指示的系統(tǒng)屬性岁钓。
22、Runtime:
(1)每個(gè) Java 應(yīng)用程序都有一個(gè) Runtime 類實(shí)例微王,使應(yīng)用程序能夠與其運(yùn)行的環(huán)境相連接屡限。
可以通過(guò) getRuntime 方法獲取當(dāng)前運(yùn)行時(shí)。 應(yīng)用程序不能創(chuàng)建自己的 Runtime 類實(shí)例炕倘。
(2)該類沒(méi)有構(gòu)造函數(shù)钧大,也就是它不能直接創(chuàng)建對(duì)象,但是它里里面的方法又不是靜態(tài)的
罩旋,故它一定有一個(gè)方法返回本類對(duì)象
(3)故該類是單例設(shè)計(jì)模式啊央,保證在內(nèi)存中只有一個(gè)對(duì)象
(4)方法摘要:
Process exec(String command) 在單獨(dú)的進(jìn)程中執(zhí)行指定的字符串命令
void gc() 運(yùn)行垃圾回收器。
static Runtime getRuntime() 返回與當(dāng)前 Java 應(yīng)用程序相關(guān)的運(yùn)行時(shí)對(duì)象
void exit(int status) 通過(guò)啟動(dòng)虛擬機(jī)的關(guān)閉序列涨醋,終止當(dāng)前正在運(yùn)行的 Java 虛擬機(jī)
23瓜饥、Date:
(1)Date接口表示特定的瞬間,精確到毫秒
(2)構(gòu)造方法
Date() 分配 Date 對(duì)象并初始化此對(duì)象浴骂,以表示分配它的時(shí)間(精確到毫秒)乓土。
Date(long date) 分配Date對(duì)象并初始化此對(duì)象,以表示自從標(biāo)準(zhǔn)基準(zhǔn)時(shí)間(稱為“歷元(epoch)”溯警,
即1970年1月1日00:00:00GMT)以來(lái)的指定毫秒數(shù)趣苏。
(3)方法摘要:
int compareTo(Date anotherDate) 比較兩個(gè)日期的順序。
boolean equals(Object obj) 比較兩個(gè)日期的相等性梯轻。
24食磕、Calendar:
(1)直接已知子類: GregorianCalendar
(2)構(gòu)造方法:
protected Calendar() 構(gòu)造一個(gè)帶有默認(rèn)時(shí)區(qū)和語(yǔ)言環(huán)境的 Calendar。
protected Calendar(TimeZone zone, Locale aLocale) 構(gòu)造一個(gè)帶有指定時(shí)區(qū)和語(yǔ)言環(huán)境的 Calendar檩淋。
(3)方法摘要:
static Calendar getInstance() 使用默認(rèn)時(shí)區(qū)和語(yǔ)言環(huán)境獲得一個(gè)日歷芬为。

四、jdk6的新特性(java7 ??)
(1)靜態(tài)導(dǎo)入:
**import語(yǔ)句可以導(dǎo)入一個(gè)類或某個(gè)包中的所有類
**import static語(yǔ)句導(dǎo)入一個(gè)類中的某個(gè)靜態(tài)方法或所有靜態(tài)方法
靜態(tài)導(dǎo)入后蟀悦,靜態(tài)方法前面就不用寫(xiě)類名.方法的方式類調(diào)用
*語(yǔ)法舉例:
import static java.lang.Math.sin;//導(dǎo)入一個(gè)靜態(tài)方法
import static java.lang.Math.
; //導(dǎo)入一個(gè)類中的所有靜態(tài)方法
**靜態(tài)導(dǎo)入使用注意:
當(dāng)類名重復(fù)時(shí)媚朦,需要制定具體的包名;
當(dāng)方法重名時(shí)日戈,需要制定具體所屬的對(duì)象或者類
(2)可變參數(shù):
**可變參數(shù)的特點(diǎn):
*可變參數(shù)只能出現(xiàn)在參數(shù)列表的最后询张;
*...位于變量類型和變量名之間,前后有無(wú)空格都可以;
*調(diào)用可變參數(shù)的方法時(shí)浙炼,編譯器為該可變參數(shù)隱含創(chuàng)建一個(gè)數(shù)組份氧,
在方法體中以數(shù)組的形式訪問(wèn)可變參數(shù)唯袄。
**可變參數(shù)舉例:
*變量類型... 變量名 如 int... arr 表示可變參數(shù)數(shù)組
*public static void show(String str , int... arr){}
(3)增強(qiáng)for循環(huán):
**語(yǔ)法:
for ( type 變量名:集合變量名 ) { … }
**注意事項(xiàng):
迭代變量必須在( )中定義!
集合變量可以是數(shù)組或?qū)崿F(xiàn)了Iterable接口的集合類
**舉例:
public static int add(int x,int ...args) {
int sum = x;
for(int arg:args) {
sum += arg;
}
return sum;
}
**增強(qiáng)for循環(huán)代替了迭代器使用的不爽蜗帜,簡(jiǎn)化書(shū)寫(xiě)
**增強(qiáng)for循環(huán)局限性:
對(duì)集合或者數(shù)組進(jìn)行遍歷時(shí)恋拷,只能取元素,不能對(duì)集合進(jìn)行操作
(4)基本數(shù)據(jù)類型的自動(dòng)裝箱和拆箱
**基本數(shù)據(jù)類型
byte ---> Byte
short ---> Short
int ---> Integer
long ---> Long
float ---> Float
double ---> Double
char ---> Character
boolean ---> Boolean
**例子:
**裝箱:自動(dòng)把一個(gè)基本數(shù)據(jù)類型的數(shù)據(jù)裝箱成一個(gè)該類型數(shù)據(jù)的對(duì)象引用
Integer i = 3;(jdk1.5之前這樣寫(xiě)是不行的厅缺,編譯報(bào)錯(cuò))
**拆箱:自動(dòng)把一個(gè)基本數(shù)據(jù)類型的對(duì)象引用拆箱成一個(gè)基本數(shù)據(jù)類型的數(shù)據(jù)蔬顾,再參與運(yùn)算
Integer i = 12;
sop(i+4);
**享元模式:
Integer num1 = 12;
Integer num2 = 12;
System.out.println(num1 == num2);//打印true

            Integer num5 = Integer.valueOf(12);
            Integer num6 = Integer.valueOf(12);
            System.out.println(num5 == num6);//打印true

            Integer num3 = 129;
            Integer num4 = 129;
            System.out.println(num3 == num4);//打印false

            為什么前面的返回true而后面的運(yùn)算返回false呢?
            對(duì)于基本數(shù)據(jù)類型的整數(shù)湘捎,裝箱成Integer對(duì)象時(shí)诀豁,如果該數(shù)值在一個(gè)字節(jié)內(nèi),(-128~127),
            一旦裝箱成Integer對(duì)象后窥妇,就把它緩存到磁里面舷胜,當(dāng)下次,又把該數(shù)值封裝成Integer對(duì)象時(shí)
            會(huì)先看磁里面有沒(méi)有該對(duì)象活翩,有就直接拿出來(lái)用烹骨,這樣就節(jié)省了內(nèi)存空間。因?yàn)楸容^小的整數(shù)材泄,
            用的頻率比較高展氓,就沒(méi)必要每個(gè)對(duì)象都分配一個(gè)內(nèi)存空間。
            這就是享元模式脸爱!比如26個(gè)英文字母,10個(gè)阿拉伯?dāng)?shù)字
(5)枚舉
    **為什么要有枚舉未妹?
        問(wèn)題:要定義星期幾或性別的變量簿废,該怎么定義?假設(shè)用1-7分別表示星期一到星期日络它,
        但有人可能會(huì)寫(xiě)成int weekday = 0;或即使使用常量方式也無(wú)法阻止意外族檬。

        枚舉就是要讓某個(gè)類型的變量的取值只能為若干個(gè)固定值中的一個(gè),否則化戳,編譯器就會(huì)報(bào)錯(cuò)单料。
        枚舉可以讓編譯器在編譯時(shí)就可以控制源程序中填寫(xiě)的非法值,
        普通變量的方式在開(kāi)發(fā)階段無(wú)法實(shí)現(xiàn)這一目標(biāo)点楼。
    **用普通類如何實(shí)現(xiàn)枚舉的功能扫尖?定義一個(gè)Weekday類來(lái)模擬實(shí)現(xiàn):
        步驟:
            *私有化構(gòu)造方法
            *每個(gè)元素分別用一個(gè)公有的靜態(tài)成員變量表示(public static final)
            *可以有若干公有方法或抽象方法。采用抽象方法定義nextDay就將大量的if.else語(yǔ)句
             轉(zhuǎn)移成了一個(gè)個(gè)獨(dú)立的類掠廓。
    **枚舉的應(yīng)用:
        舉例:定義一個(gè)Weekday的枚舉换怖。
        擴(kuò)展:枚舉類的values,valueOf,name,toString,ordinal等方法
             (記住,講課時(shí)要先于自定義方法前介紹蟀瞧,講課更流暢)
        總結(jié):枚舉是一種特殊的類沉颂,其中的每個(gè)元素都是該類的一個(gè)實(shí)例對(duì)象条摸。 
              例如可以調(diào)用WeekDay.SUN.getClass().getName和WeekDay.class.getName()。
    **枚舉的高級(jí)應(yīng)用:
        **枚舉就相當(dāng)于一個(gè)類铸屉,其中也可以定義構(gòu)造方法钉蒲、成員變量、普通方法和抽象方法彻坛。
        **枚舉元素必須位于枚舉體中的最開(kāi)始部分顷啼,枚舉元素列表的后要有分號(hào)與其他成員分隔。
          把枚舉中的成員方法或變量等放在枚舉元素的前面小压,編譯器報(bào)告錯(cuò)誤线梗。
        **帶構(gòu)造方法的枚舉
          構(gòu)造方法必須定義成私有的
          如果有多個(gè)構(gòu)造方法,該如何選擇哪個(gè)構(gòu)造方法怠益?
          枚舉元素MON和MON()的效果一樣仪搔,都是調(diào)用默認(rèn)的構(gòu)造方法。
        **帶方法的枚舉
          定義枚舉TrafficLamp
          實(shí)現(xiàn)普通的next方法
          實(shí)現(xiàn)抽象的next方法:每個(gè)元素分別是由枚舉類的子類來(lái)生成的實(shí)例對(duì)象蜻牢,
          這些子類采用類似內(nèi)部類的方式進(jìn)行定義烤咧。增加上表示時(shí)間的構(gòu)造方法     
        **枚舉只有一個(gè)成員時(shí),就可以作為一種單例的實(shí)現(xiàn)方式抢呆。     
(6)泛型:
    **泛型是提供給javac編譯器使用的煮嫌,可以限定集合中的輸入類型,讓編譯器擋住源程序中的非法輸入抱虐,
      編譯器編譯帶類型說(shuō)明的集合時(shí)會(huì)去除掉“類型”信息昌阿,使程序運(yùn)行效率不受影響,
      對(duì)于參數(shù)化的泛型類型恳邀,getClass()方法的返回值和原始類型完全一樣懦冰。
      由于編譯生成的字節(jié)碼會(huì)去掉泛型的類型信息,只要能跳過(guò)編譯器谣沸,
      就可以往某個(gè)泛型集合中加入其它類型的數(shù)據(jù)刷钢,例如,用反射得到集合乳附,再調(diào)用其add方法即可内地。
    **ArrayList<E>類定義和ArrayList<Integer>類引用中涉及如下術(shù)語(yǔ):
        整個(gè)稱為ArrayList<E>泛型類型
        ArrayList<E>中的E稱為類型變量或類型參數(shù)
        整個(gè)ArrayList<Integer>稱為參數(shù)化的類型
        ArrayList<Integer>中的Integer稱為類型參數(shù)的實(shí)例或?qū)嶋H類型參數(shù)
        ArrayList<Integer>中的<>念著typeof
        ArrayList稱為原始類型
    **參數(shù)化類型與原始類型的兼容性:
        參數(shù)化類型可以引用一個(gè)原始類型的對(duì)象,編譯報(bào)告警告赋除,
        例如阱缓,?Collection<String> c = new Vector();//可不可以,不就是編譯器一句話的事嗎贤重?
        原始類型可以引用一個(gè)參數(shù)化類型的對(duì)象宽菜,編譯報(bào)告警告路星,
        例如茎毁,?Collection c = new Vector<String>();//原來(lái)的方法接受一個(gè)集合參數(shù),新的類型也要能傳進(jìn)去
    **參數(shù)化類型不考慮類型參數(shù)的繼承關(guān)系:
        Vector<String> v = new Vector<Object>(); //錯(cuò)誤!///不寫(xiě)<Object>沒(méi)錯(cuò)秸妥,寫(xiě)了就是明知故犯
        Vector<Object> v = new Vector<String>(); //也錯(cuò)誤!
        編譯器不允許創(chuàng)建泛型變量的數(shù)組。即在創(chuàng)建數(shù)組實(shí)例時(shí)沃粗,
        數(shù)組的元素不能使用參數(shù)化的類型粥惧,
        例如,下面語(yǔ)句有錯(cuò)誤:
            Vector<Integer> vectorList[] = new Vector<Integer>[10];
    **泛型限定:
        **限定通配符的上邊界:
            正確:Vector<? extends Number> x = new Vector<Integer>();
            錯(cuò)誤:Vector<? extends Number> x = new Vector<String>();
        **限定通配符的下邊界:
            正確:Vector<? super Integer> x = new Vector<Number>();
            錯(cuò)誤:Vector<? super Integer> x = new Vector<Byte>();
        **提示:
            限定通配符總是包括自己最盅。
            ?只能用作引用突雪,不能用它去給其他變量賦值
            Vector<? extends Number> y = new Vector<Integer>();
            Vector<Number> x = y;
            上面的代碼錯(cuò)誤,原理與Vector<Object > x11 = new Vector<String>();相似涡贱,
            只能通過(guò)強(qiáng)制類型轉(zhuǎn)換方式來(lái)賦值咏删。

五、IO流
1问词、IO流概述
(1)用來(lái)處理設(shè)備(硬盤(pán)督函,控制臺(tái),內(nèi)存)間的數(shù)據(jù)激挪。
(2)java中對(duì)數(shù)據(jù)的操作都是通過(guò)流的方式辰狡。
(3)java用于操作流的類都在io包中。
(4)按照流操作的數(shù)據(jù)的類型不同:分為字節(jié)流和字符流垄分。字符流是為了方便中文的操作而來(lái)的宛篇。
(5)按照流的流向不同分為:輸入流,輸出流
2薄湿、IO流常用基類:
(1)字節(jié)流
輸出字節(jié)流:OutputStream:字節(jié)寫(xiě)入流抽象類
|--->FileOutputStream:
字節(jié)寫(xiě)入流
|--->BufferedOutputStream:
字節(jié)寫(xiě)入流緩沖區(qū)
|--->PrintStream:
打印流
輸入字節(jié)流:InputStream:字節(jié)讀取流抽象類
|--->FileInputStream:
字節(jié)讀取流
|--->BufferedInputStream:
字節(jié)讀取流緩沖區(qū)
(2)字符流
輸出字符流:Writer:字符寫(xiě)入流的抽象
|--->FileWriter:
字符寫(xiě)入流
|--->BufferedWriter:
字符寫(xiě)入流緩沖區(qū)
|--->OutputStreamWriter:
字符通向字節(jié)的轉(zhuǎn)換流(涉及鍵盤(pán)錄入時(shí)用)
|--->PrintWriter:
打印流叫倍,可處理各種類型的數(shù)據(jù)
輸入字符流:Reader: 字符讀取流的抽象類
|--->FileReader:
字符讀取流
|--->LineNumberReader:
跟蹤行號(hào)的緩沖字符讀取流
|--->BufferedReader:
字符讀取流緩沖區(qū)
|--->InputStreamReader:
字節(jié)通向字符的轉(zhuǎn)換流(涉及鍵盤(pán)錄入時(shí)用)
(3)IO流常用基類方法摘要:
**字節(jié)寫(xiě)入流:OutputStream:
void close() 關(guān)閉此輸出流并釋放與此流有關(guān)的所有系統(tǒng)資源。
void flush()刷新此輸出流并強(qiáng)制寫(xiě)出所有緩沖的輸出字節(jié)豺瘤。
abstract void write(int b) 將指定的字節(jié)寫(xiě)入此輸出流段标。
void write(byte[] b) 將 b.length 個(gè)字節(jié)從指定的 byte 數(shù)組寫(xiě)入此輸出流。
void write(byte[] b, int off, int len)
將指定 byte 數(shù)組中從偏移量 off 開(kāi)始的 len 個(gè)字節(jié)寫(xiě)入此輸出流炉奴。
**字節(jié)讀取流:InputStream:
void close() 關(guān)閉此輸入流并釋放與該流關(guān)聯(lián)的所有系統(tǒng)資源。
int available() (特有方法I吒瞻赶!)
返回此輸入流下一個(gè)方法調(diào)用可以不受阻塞地從此輸入流讀取(或跳過(guò))的估計(jì)字節(jié)數(shù)派任。
abstract int read() 從輸入流中讀取數(shù)據(jù)的下一個(gè)字節(jié)砸逊。
int read(byte[] b) 從輸入流中讀取一定數(shù)量的字節(jié),并將其存儲(chǔ)在緩沖區(qū)數(shù)組 b 中掌逛。
int read(byte[] b, int off, int len) 將輸入流中最多 len 個(gè)數(shù)據(jù)字節(jié)讀入 byte 數(shù)組师逸。
long skip(long n) 跳過(guò)和丟棄此輸入流中數(shù)據(jù)的 n 個(gè)字節(jié)。

    **字符寫(xiě)入流:Writer:
        abstract  void close() 關(guān)閉此流豆混,但要先刷新它篓像。
        abstract  void flush() 刷新該流的緩沖动知。
        void write(int c) 寫(xiě)入單個(gè)字符。
        void write(char[] cbuf) 寫(xiě)入字符數(shù)組员辩。          
        abstract  void write(char[] cbuf, int off, int len) 寫(xiě)入字符數(shù)組的某一部分盒粮。 
        void write(String str) 寫(xiě)入字符串。 
        void write(String str, int off, int len) 寫(xiě)入字符串的某一部分奠滑。 

    **字符讀取流:Reader:
        abstract  void close() 關(guān)閉該流并釋放與之關(guān)聯(lián)的所有資源丹皱。
        int read() 讀取單個(gè)字符。
        int read(char[] cbuf)  將字符讀入數(shù)組
        abstract  int read(char[] cbuf, int off, int len) 將字符讀入數(shù)組的某一部分宋税。
        long skip(long n)  跳過(guò)字符摊崭。 

3、IO流常用字節(jié)流基類的子類:
**寫(xiě)入流:
(1)FileOutputStream:
**構(gòu)造方法:
FileOutputStream(String name)
創(chuàng)建一個(gè)向具有指定名稱的文件中寫(xiě)入數(shù)據(jù)的輸出文件流杰赛。
FileOutputStream(String name, boolean append)
創(chuàng)建一個(gè)向具有指定 name 的文件中寫(xiě)入數(shù)據(jù)的輸出文件流呢簸。
FileOutputStream(File file)
創(chuàng)建一個(gè)向指定 File 對(duì)象表示的文件中寫(xiě)入數(shù)據(jù)的文件輸出流。
FileOutputStream(File file, boolean append)
創(chuàng)建一個(gè)向指定 File 對(duì)象表示的文件中寫(xiě)入數(shù)據(jù)的文件輸出流淆攻。
**方法摘要:
public void flush()
void close() 關(guān)閉此文件輸出流并釋放與此流有關(guān)的所有系統(tǒng)資源阔墩。
void write(int b) 將指定字節(jié)寫(xiě)入此文件輸出流。
void write(byte[] b, int off, int len)
將指定 byte 數(shù)組中從偏移量 off 開(kāi)始的 len 個(gè)字節(jié)寫(xiě)入此文件輸出流瓶珊。
void write(int b) 將指定字節(jié)寫(xiě)入此文件輸出流啸箫。
(2)BufferedOutputStream:
**構(gòu)造方法:
BufferedOutputStream(OutputStream out)
創(chuàng)建一個(gè)新的緩沖輸出流,以將數(shù)據(jù)寫(xiě)入指定的底層輸出流伞芹。
BufferedOutputStream(OutputStream out, int size)
創(chuàng)建一個(gè)新的緩沖輸出流忘苛,以將具有指定緩沖區(qū)大小的數(shù)據(jù)寫(xiě)入指定的底層輸出流。
**方法摘要:
void flush() 刷新此緩沖的輸出流唱较。
void write(byte[] b, int off, int len)
將指定 byte 數(shù)組中從偏移量 off 開(kāi)始的 len 個(gè)字節(jié)寫(xiě)入此緩沖的輸出流扎唾。
void write(int b) 將指定的字節(jié)寫(xiě)入此緩沖的輸出流。
(3)PrintStream:打印流南缓,可將各種類型的數(shù)據(jù)原樣打印胸遇,有自動(dòng)刷新功能
**構(gòu)造方法:
PrintStream(String fileName)
創(chuàng)建具有指定文件名稱且不帶自動(dòng)行刷新的新打印流。
PrintStream(File file)
創(chuàng)建具有指定文件且不帶自動(dòng)行刷新的新打印流汉形。
PrintStream(OutputStream out)
創(chuàng)建新的打印流纸镊。
PrintStream(OutputStream out, boolean autoFlush) (當(dāng)autoFlush為true時(shí)具有自動(dòng)刷新功能)
創(chuàng)建新的打印流。
**方法摘要:
PrintStream append(char c)
將指定字符添加到此輸出流概疆。
void close()
關(guān)閉流逗威。
void flush()
刷新該流的緩沖。
void print(各種類型的數(shù)據(jù):)
打印各種類型的數(shù)據(jù)
void println(各種類型的數(shù)據(jù):):自動(dòng)換行
打印各種類型的數(shù)據(jù)
void write(byte[] buf, int off, int len)
將 len 字節(jié)從指定的初始偏移量為 off 的 byte 數(shù)組寫(xiě)入此流岔冀。
void write(int b)
將指定的字節(jié)寫(xiě)入此流凯旭。

**讀取流:
(1)FileInputStream:
    **構(gòu)造方法:
    FileInputStream(String name) 
        通過(guò)打開(kāi)一個(gè)到實(shí)際文件的連接來(lái)創(chuàng)建一個(gè) FileInputStream,
        該文件通過(guò)文件系統(tǒng)中的路徑名 name 指定。
    FileInputStream(File file) 
        通過(guò)打開(kāi)一個(gè)到實(shí)際文件的連接來(lái)創(chuàng)建一個(gè) FileInputStream罐呼,
        該文件通過(guò)文件系統(tǒng)中的 File 對(duì)象 file 指定鞠柄。
    **方法摘要:
    int available() (字節(jié)讀取流特有方法!E摺春锋!)
        返回下一次對(duì)此輸入流調(diào)用的方法可以不受阻塞地從此輸入流讀取(或跳過(guò))的估計(jì)剩余字節(jié)數(shù)差凹。
    int read() 
        從此輸入流中讀取一個(gè)數(shù)據(jù)字節(jié)期奔。 
    int read(byte[] b) 
        從此輸入流中將最多 b.length 個(gè)字節(jié)的數(shù)據(jù)讀入一個(gè) byte 數(shù)組中。 
    int read(byte[] b, int off, int len) 
        從此輸入流中將最多 len 個(gè)字節(jié)的數(shù)據(jù)讀入一個(gè) byte 數(shù)組中危尿。 
    long skip(long n) 
        從輸入流中跳過(guò)并丟棄 n 個(gè)字節(jié)的數(shù)據(jù)呐萌。 
(2)BufferedInputStream:
    **構(gòu)造方法:
    BufferedInputStream(InputStream in) 
        創(chuàng)建一個(gè) BufferedInputStream 并保存其參數(shù),即輸入流 in谊娇,以便將來(lái)使用肺孤。 
    BufferedInputStream(InputStream in, int size) 
        創(chuàng)建具有指定緩沖區(qū)大小的 BufferedInputStream 并保存其參數(shù),即輸入流 in济欢,以便將來(lái)使用赠堵。 
    **方法摘要:
    int available() (字節(jié)讀取流特有方法!7ㄈ臁茫叭!)
        返回可以從此輸入流讀取(或跳過(guò))半等、且不受此輸入流接下來(lái)的方法調(diào)用阻塞的估計(jì)字節(jié)數(shù)揍愁。 
    int read() 
        參見(jiàn) InputStream 的 read 方法的常規(guī)協(xié)定。 
    int read(byte[] b, int off, int len) 
        從此字節(jié)輸入流中給定偏移量處開(kāi)始將各字節(jié)讀取到指定的 byte 數(shù)組中杀饵。 
    long skip(long n) 
        參見(jiàn) InputStream 的 skip 方法的常規(guī)協(xié)定莽囤。

4、字符流常用基類的子類
**寫(xiě)入流:
(1)FileWriter:
**構(gòu)造方法:
FileWriter(String fileName)
根據(jù)給定的文件名構(gòu)造一個(gè) FileWriter 對(duì)象切距。
FileWriter(String fileName, boolean append)
根據(jù)給定的文件名以及指示是否附加寫(xiě)入數(shù)據(jù)的 boolean 值來(lái)構(gòu)造 FileWriter 對(duì)象朽缎。
FileWriter(File file)
根據(jù)給定的 File 對(duì)象構(gòu)造一個(gè) FileWriter 對(duì)象。
FileWriter(File file, boolean append)
根據(jù)給定的 File 對(duì)象構(gòu)造一個(gè) FileWriter 對(duì)象谜悟。
FileWriter(FileDescriptor fd)
構(gòu)造與某個(gè)文件描述符相關(guān)聯(lián)的 FileWriter 對(duì)象饵沧。
**方法摘要:跟Writer一樣
abstract void close() 關(guān)閉此流,但要先刷新它赌躺。
abstract void flush() 刷新該流的緩沖。
void write(int c) 寫(xiě)入單個(gè)字符羡儿。
void write(char[] cbuf) 寫(xiě)入字符數(shù)組礼患。
abstract void write(char[] cbuf, int off, int len) 寫(xiě)入字符數(shù)組的某一部分。
void write(String str) 寫(xiě)入字符串。
void write(String str, int off, int len) 寫(xiě)入字符串的某一部分缅叠。
(2)BufferedWriter:
**構(gòu)造方法:
BufferedWriter(Writer out)
創(chuàng)建一個(gè)使用默認(rèn)大小輸出緩沖區(qū)的緩沖字符輸出流悄泥。
BufferedWriter(Writer out, int sz)
創(chuàng)建一個(gè)使用給定大小輸出緩沖區(qū)的新緩沖字符輸出流。
**方法摘要:
void close()
關(guān)閉此流肤粱,但要先刷新它弹囚。
void flush()
刷新該流的緩沖。
void newLine()
寫(xiě)入一個(gè)行分隔符领曼。
void write(char[] cbuf, int off, int len)
寫(xiě)入字符數(shù)組的某一部分鸥鹉。
void write(int c)
寫(xiě)入單個(gè)字符。
void write(String s, int off, int len)
寫(xiě)入字符串的某一部分庶骄。
(3)OutputStreamWriter:字符通向字節(jié)的轉(zhuǎn)換流
**構(gòu)造方法:
OutputStreamWriter(OutputStream out)
創(chuàng)建使用默認(rèn)字符編碼的 OutputStreamWriter毁渗。
**方法摘要:
void write(char[] cbuf, int off, int len)
寫(xiě)入字符數(shù)組的某一部分。
void write(int c)
寫(xiě)入單個(gè)字符单刁。
void write(String str, int off, int len)
寫(xiě)入字符串的某一部分灸异。
(4)PrintWriter:
**構(gòu)造方法:
PrintWriter(String fileName)
創(chuàng)建具有指定文件名稱且不帶自動(dòng)行刷新的新 PrintWriter。
PrintWriter(File file)
使用指定文件創(chuàng)建不具有自動(dòng)行刷新的新 PrintWriter羔飞。
PrintWriter(Writer out)
創(chuàng)建不帶自動(dòng)行刷新的新 PrintWriter肺樟。
PrintWriter(Writer out, boolean autoFlush)
創(chuàng)建新 PrintWriter。
PrintWriter(OutputStream out)
根據(jù)現(xiàn)有的 OutputStream 創(chuàng)建不帶自動(dòng)行刷新的新 PrintWriter逻淌。
PrintWriter(OutputStream out, boolean autoFlush)
通過(guò)現(xiàn)有的 OutputStream 創(chuàng)建新的 PrintWriter么伯。

    **方法摘要:
    PrintWriter append(char c) 
        將指定字符添加到此 writer。 
    void print(各種類型的數(shù)據(jù):) 
        打印各種類型的數(shù)據(jù) 
    void println(各種類型的數(shù)據(jù):):自動(dòng)換行
        打印各種類型的數(shù)據(jù)
    void write(char[] buf) 
        寫(xiě)入字符數(shù)組恍风。 
    void write(char[] buf, int off, int len) 
        寫(xiě)入字符數(shù)組的某一部分蹦狂。 
    void write(int c) 
        寫(xiě)入單個(gè)字符。 
    void write(String s) 
        寫(xiě)入字符串朋贬。 
    void write(String s, int off, int len) 
        寫(xiě)入字符串的某一部分凯楔。 
**讀取流:
(1)FileReader:
    **構(gòu)造方法:
    FileReader(String fileName) 
        在給定從中讀取數(shù)據(jù)的文件名的情況下創(chuàng)建一個(gè)新 FileReader。
    FileReader(File file) 
        在給定從中讀取數(shù)據(jù)的 File 的情況下創(chuàng)建一個(gè)新 FileReader锦募。 
    FileReader(FileDescriptor fd) 
        在給定從中讀取數(shù)據(jù)的 FileDescriptor 的情況下創(chuàng)建一個(gè)新 FileReader摆屯。 
    **方法摘要:和Reader基類方法一致:
    abstract  void close() 關(guān)閉該流并釋放與之關(guān)聯(lián)的所有資源。
    int read() 讀取單個(gè)字符糠亩。
    int read(char[] cbuf)  將字符讀入數(shù)組
    abstract  int read(char[] cbuf, int off, int len) 將字符讀入數(shù)組的某一部分虐骑。
    long skip(long n)  跳過(guò)字符。 
(2)BufferedReader:
    **構(gòu)造方法:
    BufferedReader(Reader in) 
        創(chuàng)建一個(gè)使用默認(rèn)大小輸入緩沖區(qū)的緩沖字符輸入流赎线。
    **方法摘要:
    int read() 
        讀取單個(gè)字符廷没。 
    int read(char[] cbuf, int off, int len) 
        將字符讀入數(shù)組的某一部分。 
    String readLine() 
        讀取一個(gè)文本行垂寥。 
(3)InputStreamReader:字符通向字節(jié)的橋梁:
    **構(gòu)造方法:
    InputStreamReader(InputStream in) 
        創(chuàng)建一個(gè)使用默認(rèn)字符集的 InputStreamReader颠黎。
    **方法摘要:
    int read() 讀取單個(gè)字符另锋。
    int read(char[] cbuf)  將字符讀入數(shù)組
    abstract  int read(char[] cbuf, int off, int len) 將字符讀入數(shù)組的某一部分。
    long skip(long n)  跳過(guò)字符狭归。
(4)LineNumberReader:
    **構(gòu)造方法:
    LineNumberReader(Reader in) 
        使用默認(rèn)輸入緩沖區(qū)的大小創(chuàng)建新的行編號(hào) reader夭坪。
    **方法摘要:
    int read() 
        讀取單個(gè)字符。 
    int read(char[] cbuf, int off, int len) 
        將字符讀入數(shù)組中的某一部分过椎。 
    String readLine() 
        讀取文本行室梅。
    long skip(long n) 
        跳過(guò)字符。 
    int getLineNumber() 
        獲得當(dāng)前行號(hào)疚宇。 
    void setLineNumber(int lineNumber) 
        設(shè)置當(dāng)前行號(hào)亡鼠。 

6、IO流常見(jiàn)需求:
****字符流:
(1)需求1:在硬盤(pán)上創(chuàng)建一個(gè)文件并寫(xiě)入信息
用字符寫(xiě)入流:FileWriter
FileWriter fw = new FileWriter("g:\filewriter.txt");
fw.write("輸入信息");
fw.write("也可以寫(xiě)入字符數(shù)組".toCharArray());
fw.flush();
fw.close();
(2)需求2:在原有文件上續(xù)寫(xiě)數(shù)據(jù)
FileWriter fw = new FileWriter("g:\filewriter.txt",true);
fw.write("還可以續(xù)寫(xiě)信息");
fw.write("也可以寫(xiě)入字符數(shù)組".toCharArray());
fw.flush();
fw.close();
(3)需求3:讀取硬盤(pán)上的文本文件灰嫉,并將數(shù)據(jù)打印在控制臺(tái)
FileReader fr = new FileReader("g:\filewriter.txt");
**第一種讀取方法:一個(gè)一個(gè)字節(jié)的讀
int ch = 0;
ch = fr.read();
sop((char)ch);
fr.close();
**第二種讀取方法:利用數(shù)組來(lái)提高效率
char[] buf = new char[1024];
int len = 0;
while((len = fr.read(buf))!=-1)
{
sop(new String(buf,0,len));
}
fr.close();
(4)需求4:拷貝文本文件
利用緩沖區(qū)提高數(shù)據(jù)讀寫(xiě)效率
(無(wú)緩沖區(qū)就相當(dāng)于一滴一滴的喝水拆宛,有緩沖區(qū)就相當(dāng)于一杯一杯的喝水)
BufferedReader bufr = new BufferedReader(new FileReader("g:\filewriter.txt"));
BufferedWriter bufw = new BufferedWriter(new FileWriter("d:\copyfilewriter.txt"));
String line = null;
while((line = bufr.readLine())!=null)
{
burw.write(line);
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
****字節(jié)流:字節(jié)流寫(xiě)入時(shí)沒(méi)有刷新
(1)需求1:在硬盤(pán)上創(chuàng)建一個(gè)文件并寫(xiě)入信息(字節(jié)流寫(xiě)入時(shí)沒(méi)有刷新)
FileOutputStream fos = new FileOutputStream("g:\filestream.txt");
fos.write(97);//寫(xiě)入一個(gè)字節(jié),int:97代表寫(xiě)入char:a
fos.write("也可以寫(xiě)入字節(jié)數(shù)組".getBytes());//通常使用此種方式寫(xiě)入,直觀讼撒!
fos.close();
(2)需求2:在硬盤(pán)已有文件上續(xù)寫(xiě)數(shù)據(jù)(字節(jié)流寫(xiě)入時(shí)沒(méi)有刷新)
FileOutputStream fos = new FileOutputStream("g:\filestream.txt",true);
fos.write("創(chuàng)建字節(jié)寫(xiě)入流時(shí)浑厚,傳進(jìn)去一個(gè)true參數(shù)就可以繼續(xù)寫(xiě)入信息".getBytes());
fos.close();
(3)需求3:讀取硬盤(pán)上的文件
FileInputStream fis = new FileInputStream("g:\filestream.txt");
**第一種讀法:一個(gè)字節(jié)一個(gè)字節(jié)的讀(此種讀法慢)
int ch = 0;
while((ch = fis.read())!=-1)
{
sop((char)ch);
}
**第一種讀法:利用字節(jié)數(shù)組讀(此種讀法效率有一定提高)
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read())!=-1)
{
sop(new String(buf,0,len));
}
(4)需求4:拷貝字節(jié)文件,如圖片或者M(jìn)P3或者電影
**第一種拷貝:不帶緩沖區(qū)(慢根盒,還是效率問(wèn)題)
FileInputStream fis = new FileInputStream("g:\1.mp3");
FileOutputStream fos = new FileOutputStream("g:\copy1.mp3");
byte[] buf = new byte[1024];
int len = 0;
while((len = fis.read(buf))!=-1)
{
fos.write(buf,0,len);//字節(jié)流寫(xiě)入無(wú)需刷新
}
fis.close();
fos.close();
**第二種拷貝:帶緩沖區(qū)钳幅,高效
BufferedInputStream bufi = new BufferedInputStream(new FileInputStream("g:\1.mp3"));
BufferedOutputStream bufo = new BufferedOutputStream(new FileOutputStream("g:\copy1.mp3"));
int ch = 0;
while((ch = bufi.read())!=-1)
{
bufo.write(ch);
}
bufi.close();
bufo.close();
****轉(zhuǎn)換流:
(1)需求1:讀取一個(gè)鍵盤(pán)錄入
InputStream in = System.in;//創(chuàng)建一個(gè)鍵盤(pán)錄入流,流不關(guān)則可以一直錄入
int by1 = in.read();//一次讀一個(gè)字節(jié)
int by2 = in.read();//一次讀一個(gè)字節(jié)
sop(by1);//假設(shè)鍵盤(pán)錄入的是abcd,則打印a
sop(by2);//假設(shè)鍵盤(pán)錄入的是abcd,則打印b
in.close();
(2)需求2:鍵盤(pán)錄入一行數(shù)據(jù)打印一行數(shù)據(jù)炎滞,如果錄入的是over則結(jié)束錄入
InputStream in = System.in;
StringBuilder sb = new StringBuilder();
while(true)
{
int ch = in.read();
if(ch=='\r')
continue;
if(ch=='\n')
{
String line = sb.toString();
if("over".equals(line))
break;
sop(line.toUpperCase());//輸出大寫(xiě)
sb.delete(0.sb.length());//清除上一行錄入的數(shù)據(jù)

        }
        else
            sb.append((char)ch);
    }
    in.close();
(3)需求3:發(fā)現(xiàn)需求2中其實(shí)就是讀一行的原理敢艰,故引入字節(jié)通向字符的橋梁:InputStreamReader
    為提高效率加入緩沖區(qū):
    BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    String line = null;
    while((line = bufr.readLine())!=null)
    {
        if("over".equals(line))
            break;
        sop(line.toUpperCase());//輸出大寫(xiě)
    }
    bufr.close();
(4)需求4:鍵盤(pán)錄入數(shù)據(jù)并打印到控制臺(tái)
    BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));
    String line = null;
    while((line = bufr.readLine())!=null)
    {   
        if("over".equals(line))
            break;
        bufw.write(line.toUpperCase());
        bufw.newLine();
        bufw.flush();   
    }
    bufr.close();
    bufw.close();
(5)需求5:將鍵盤(pán)錄入的數(shù)據(jù)存儲(chǔ)到硬盤(pán)文件
    則只需將(4)中的
    BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));
    改為:
    BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(new FileWriter("g:\\demo.txt")));
    即:
    BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(new FileWriter("g:\\demo.txt")));
    String line = null;
    while((line = bufr.readLine())!=null)
    {   
        if("over".equals(line))
            break;
        bufw.write(line.toUpperCase());
        bufw.newLine();
        bufw.flush();   
    }
    bufr.close();
    bufw.close();
(6)需求6:將硬盤(pán)文件的數(shù)據(jù)打印到控制臺(tái)
    則只需將(4)中的
    BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
    改為:
    BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileReader("g:\\demo.txt")));
    即:
    BufferedReader bufr = new BufferedReader(new InputStreamReader(new FileReader("g:\\demo.txt")));
    BufferedWriter bufw = new BufferedWriter(new OntputStreamWriter(System.out));
    String line = null;
    while((line = bufr.readLine())!=null)
    {   
        if("over".equals(line))
            break;
        bufw.write(line.toUpperCase());
        bufw.newLine();
        bufw.flush();   
    }
    bufr.close();
    bufw.close();

7、流操作的規(guī)律:
****流操作的難點(diǎn):流對(duì)象很多册赛,不知道具體用哪個(gè)
****規(guī)律:
(1)第一步:先明確源和目的
源:
文本:用Reader
字節(jié):用InputStream
目的:
文本:用Writer
字節(jié):用OutputStream
(2)第二步:明確是不是純文本
是:用字符流钠导;
不是:用字節(jié)流
(3)第三步:明確流體系后,通過(guò)設(shè)備來(lái)明確具體使用哪個(gè)流對(duì)象
源設(shè)備:
鍵盤(pán):System.in
硬盤(pán):文件流File
內(nèi)存:數(shù)組流ArrayStream
目的設(shè)備:
鍵盤(pán):System.out
硬盤(pán):文件流File
內(nèi)存:數(shù)組流ArrayStream
8森瘪、File類
構(gòu)造方法:
File(String pathname)
通過(guò)將給定路徑名字符串轉(zhuǎn)換為抽象路徑名來(lái)創(chuàng)建一個(gè)新 File 實(shí)例牡属。
File(String parent, String child)
根據(jù) parent 路徑名字符串和 child 路徑名字符串創(chuàng)建一個(gè)新 File 實(shí)例。
File(File parent, String child)
根據(jù) parent 抽象路徑名和 child 路徑名字符串創(chuàng)建一個(gè)新 File 實(shí)例扼睬。
方法摘要:
(1)創(chuàng)建:
boolean createNewFile()
當(dāng)且僅當(dāng)不存在具有此抽象路徑名指定名稱的文件時(shí)逮栅,不可分地創(chuàng)建一個(gè)新的空文件。
boolean mkdir()
創(chuàng)建一級(jí)文件夾
boolean mkdirs()
創(chuàng)建多級(jí)文件夾
(判斷):
boolean canExecute()
測(cè)試應(yīng)用程序是否可以執(zhí)行此抽象路徑名表示的文件窗宇。
boolean canRead()
測(cè)試應(yīng)用程序是否可以讀取此抽象路徑名表示的文件措伐。
boolean canWrite()
測(cè)試應(yīng)用程序是否可以修改此抽象路徑名表示的文件。
int compareTo(File pathname)
按字母順序比較兩個(gè)抽象路徑名军俊。
boolean isAbsolute()
測(cè)試此抽象路徑名是否為絕對(duì)路徑名侥加。
boolean isDirectory()
測(cè)試此抽象路徑名表示的文件是否是一個(gè)目錄拍屑。
boolean isFile()
測(cè)試此抽象路徑名表示的文件是否是一個(gè)標(biāo)準(zhǔn)文件谈宛。
boolean isHidden()
測(cè)試此抽象路徑名指定的文件是否是一個(gè)隱藏文件敲霍。
boolean exists()
測(cè)試此抽象路徑名表示的文件或目錄是否存在魁衙。
(3)獲瓤詹隆:
String getParent()
返回此抽象路徑名父目錄的路徑名字符串患雏;如果此路徑名沒(méi)有指定父目錄郭毕,則返回 null浇辜。
File getParentFile()
返回此抽象路徑名父目錄的抽象路徑名朋魔;如果此路徑名沒(méi)有指定父目錄岖研,則返回 null。
String getName()
返回由此抽象路徑名表示的文件或目錄的名稱警检。
String getPath()
將此抽象路徑名轉(zhuǎn)換為一個(gè)路徑名字符串孙援。
String getAbsolutePath()
返回此抽象路徑名的絕對(duì)路徑名字符串。
File getAbsoluteFile()
返回此抽象路徑名的絕對(duì)路徑名形式扇雕。
(4)刪除:
boolean delete()
刪除此抽象路徑名表示的文件或目錄拓售。
oid deleteOnExit()
在虛擬機(jī)終止時(shí),請(qǐng)求刪除此抽象路徑名表示的文件或目錄镶奉。
(5)獲取全部:(非常重要4∮佟!哨苛!)
String[] list()
返回一個(gè)字符串?dāng)?shù)組鸽凶,這些字符串指定此抽象路徑名表示的目錄中的文件和目錄。
String[] list(FilenameFilter filter)
返回一個(gè)字符串?dāng)?shù)組建峭,這些字符串指定此抽象路徑名表示的目錄中滿足指定過(guò)濾器的文件和目錄玻侥。
File[] listFiles()
返回一個(gè)抽象路徑名數(shù)組,這些路徑名表示此抽象路徑名表示的目錄中的文件亿蒸。
File[] listFiles(FileFilter filter)
返回抽象路徑名數(shù)組凑兰,這些路徑名表示此抽象路徑名表示的目錄中滿足指定過(guò)濾器的文件和目錄。

****FilenameFilter接口只有一個(gè)方法:
    boolean accept(File dir, String name) 
        測(cè)試指定文件是否應(yīng)該包含在某一文件列表中边锁。 
****FileFilter接口只有一個(gè)方法:
    boolean accept(File dir, String name) 
        測(cè)試指定文件是否應(yīng)該包含在某一文件列表中姑食。

8、File類常見(jiàn)需求:
(1)文件名過(guò)濾:列出給定目錄的所有.java文件
public void showFileName(File file)
{
String[] filenames = file.list(new FilenameFilter()//匿名內(nèi)部類
{
public boolean accept(File dir,String name)//復(fù)寫(xiě)唯一方法
{
return name.endsWith(".java");//列出所有.java文件
}
});
}
(2)列出指定目錄下的所有文件和文件夾(遞歸)
**示例1:不帶層次遞歸:
public static void showDir(File dir)
{
File[] files = dir.listFile();
for(int i = 0;i<files.length;i++)
{
if(files[i].isDirectory&&!files[i].isHidden())
showDir(files[i]);
else
sop(files[i]);
}
}
**示例2:帶層次遞歸:
public static void showDir(File dir,int level)
{
sop(getLevel(level)+C);//進(jìn)來(lái)先打印層次和目錄
level++;
File[] files = dir.listFile();
for(int i = 0;i<files.length;i++)
{
if(files[i].isDirectory&&!files[i].isHidden())
showDir(files[i]);
else
sop(getLevel(level)+files[i]);//是文件就打印層次和目錄
}
}
public static String getLevel(int level)
{
sop("|--");
StringBuilder sb = new StringBuilder();
for(int i=0;i<level;i++)
{
sb.inset(0."| ")
}
return sb.toString();
}
(3)需求:刪除帶內(nèi)容的目錄:
public static void removeDir(File dir)
{
File[] files = file.listFile();
for(int i = 0;i<files.length;i++)
{
if(files[i].isDirectory&&!files[i].isHidden())
removeDir(files[i]);//如果是文件夾則繼續(xù)調(diào)用函數(shù)
else//如果是文件則刪除砚蓬。注意刪除的時(shí)候打印刪除的結(jié)果矢门,防止誤刪或者重刪的情況
sop(files[i].toString()+"::"+files[i].delete());
}
sop(dir+"::"+dir.delete());
}
(4)需求:將制定目錄下的java文件的絕對(duì)路徑存儲(chǔ)到文本文件中。
思路:
**對(duì)指定目錄進(jìn)行遞歸
**獲取遞歸過(guò)程中所有java文件的路徑
**將這些路徑存儲(chǔ)到集合中
**將集合中的數(shù)據(jù)寫(xiě)入文件中
//對(duì)指定目錄進(jìn)行遞歸并將所以Java文件存儲(chǔ)到集合中
public static void getFileName(File file,ArrayList<File> arraylist){
File[] files = file.listFiles();
for (int i = 0; i < files.length; i++) {
if(files[i].isDirectory()&&!files[i].isHidden()){
getFileName(files[i],arraylist);
}else{
if(files[i].getName().endsWith(".java")){
arraylist.add(files[i]);
}
}
}
}
//將集合中所有數(shù)據(jù)存儲(chǔ)到新文件中
public static void saveFileToNewDir(ArrayList<File> arraylist,File newDir){
BufferedWriter bufw = null;
try {
bufw = new BufferedWriter(new FileWriter(newDir));
for (File file : arraylist) {
String fileAbsolutePath = file.getAbsolutePath();
bufw.write(fileAbsolutePath);
bufw.newLine();
bufw.flush();
}
} catch (Exception e) {
System.out.println("文件寫(xiě)入失敗");
}finally{
try {
if(bufw!=null)
bufw.close();
} catch (Exception e2) {
System.out.println("文件寫(xiě)入流關(guān)閉失敗");
}
}
}
9灰蛙、Properties
(1)Properties是HashTable的子類祟剔,具備Map集合的特點(diǎn),里面存儲(chǔ)的是鍵值對(duì)
(2)Properties是IO流合集合相結(jié)合的集合容器
(3)Properties的特點(diǎn)是可以用于存儲(chǔ)鍵值對(duì)形式的配置文件
(4)構(gòu)造方法:
Properties()
創(chuàng)建一個(gè)無(wú)默認(rèn)值的空屬性列表摩梧。
Properties(Properties defaults)
創(chuàng)建一個(gè)帶有指定默認(rèn)值的空屬性列表物延。
(5)方法摘要:
Object setProperty(String key, String value)
調(diào)用 Hashtable 的方法 put。
String getProperty(String key)
用指定的鍵在此屬性列表中搜索屬性仅父。
void load(InputStream inStream)
從輸入流中讀取屬性列表(鍵和元素對(duì))叛薯。
void load(Reader reader)
按簡(jiǎn)單的面向行的格式從輸入字符流中讀取屬性列表(鍵和元素對(duì))浑吟。
void list(PrintStream out)
將屬性列表輸出到指定的輸出流。
void list(PrintWriter out)
將屬性列表輸出到指定的輸出流耗溜。
void store(OutputStream out, String comments)
以適合使用 load(InputStream) 方法加載到 Properties 表中的格式组力,
將此 Properties 表中的屬性列表(鍵和元素對(duì))寫(xiě)入輸出流。
void store(Writer writer, String comments)
以適合使用 load(Reader) 方法的格式抖拴,將此 Properties 表中的
屬性列表(鍵和元素對(duì))寫(xiě)入輸出字符燎字。
Set<String> stringPropertyNames()
返回此屬性列表中的鍵集,其中該鍵及其對(duì)應(yīng)值是字符串阿宅,如果在主屬性列表中
未找到同名的鍵候衍,則還包括默認(rèn)屬性列表中不同的鍵
(6)Properties代碼示例:
public static void show()
{
Properties prop = new Properties();
prop.setProperty("張三","26");
prop.setProperty("李四","30");
prop.setProperty("王五","35");
sop(prop);
String value = prop.getProperty("張三");

    Set<String> keys = prop.stringPropertyName();
    for(String key : values)
    {
        sop(key+":"+prop.getPropety(key));
    }
}

(7)需求:記錄應(yīng)用程序的使用次數(shù),如果使用次數(shù)已到洒放,則提示用戶注冊(cè)蛉鹿。
思路:
**第一次使用時(shí)建立一個(gè)配置文件用于記錄使用次數(shù)
**每次使用都加載該配置文件,并先判斷已使用次數(shù)
**每次使用完使用次數(shù)加1往湿,寫(xiě)入配置文件
public static void main(String[] args) throws IOException{
Properties prop = new Properties();//定義Properties妖异,用來(lái)和IO流結(jié)合
File file = new File("library\time.ini");//配置文件
if(!file.exists())
file.createNewFile();//如果文件不存在則創(chuàng)建文件(用于第一次使用時(shí)創(chuàng)建文件)
FileInputStream fis = new FileInputStream(file);//定義字節(jié)讀取流,讀取配置文件中記錄的使用次數(shù)
prop.load(fis);//載入流煌茴,以獲取文件中配置的鍵值對(duì)
int count = 0;//定義使用次數(shù)
String countValue = prop.getProperty("time");//通過(guò)鍵獲取值
if(countValue!=null){//第一次時(shí)countValue為null
count = Integer.parseInt(countValue);//將字符串次數(shù)變成數(shù)字次數(shù)
if(count>3){
System.out.println("您使用次數(shù)已到随闺,繼續(xù)使用請(qǐng)注冊(cè)!");
return;
}
}
count++;//如果使用次數(shù)未到則次數(shù)加1
prop.setProperty("time", count+"");//配置新的鍵值對(duì)
FileWriter fos = new FileWriter(file);
prop.store(fos, "這是應(yīng)用程序使用次數(shù)的配置文件");//將新的鍵值對(duì)寫(xiě)入文件
fis.close();
fos.close();
}
10蔓腐、IO中的其他流:
(1)打印流:
**PrintWriter:字符打印流
****構(gòu)造方法:
PrintWriter(String fileName)
創(chuàng)建具有指定文件名稱且不帶自動(dòng)行刷新的新 PrintWriter矩乐。
PrintWriter(File file)
使用指定文件創(chuàng)建不具有自動(dòng)行刷新的新 PrintWriter。
PrintWriter(Writer out)
創(chuàng)建不帶自動(dòng)行刷新的新 PrintWriter回论。
PrintWriter(Writer out, boolean autoFlush)
自動(dòng)刷新
PrintWriter(OutputStream out)
根據(jù)現(xiàn)有的 OutputStream 創(chuàng)建不帶自動(dòng)行刷新的新 PrintWriter散罕。
PrintWriter(OutputStream out, boolean autoFlush)
自動(dòng)刷新
****方法摘要:
PrintWriter append(char c)
將指定字符添加到此 writer。
void close()
關(guān)閉該流并釋放與之關(guān)聯(lián)的所有系統(tǒng)資源傀蓉。
void flush()
刷新該流的緩沖欧漱。
void print(Object obj)
打印對(duì)象。
void print(String s)
打印字符串葬燎。
void println()
通過(guò)寫(xiě)入行分隔符字符串終止當(dāng)前行误甚。
**PrintStream:字節(jié)打印流
****構(gòu)造方法:
PrintStream(String fileName)
創(chuàng)建具有指定文件名稱且不帶自動(dòng)行刷新的新打印流。
PrintStream(File file)
創(chuàng)建具有指定文件且不帶自動(dòng)行刷新的新打印流谱净。
PrintStream(OutputStream out)
創(chuàng)建新的打印流窑邦。
PrintStream(OutputStream out, boolean autoFlush)
創(chuàng)建新的打印流。
****方法摘要:
PrintWriter append(char c)
將指定字符添加到此 writer壕探。
void close()
關(guān)閉該流并釋放與之關(guān)聯(lián)的所有系統(tǒng)資源冈钦。
void flush()
刷新該流的緩沖。
void print(Object obj)
打印對(duì)象李请。
void print(String s)
打印字符串瞧筛。
void println()
通過(guò)寫(xiě)入行分隔符字符串終止當(dāng)前行厉熟。
(2)對(duì)象系列化:
**對(duì)象實(shí)體化:找一個(gè)介質(zhì),能長(zhǎng)期的存儲(chǔ)對(duì)象较幌。
**對(duì)象的屬性在Java程序中揍瑟,都是存在于對(duì)內(nèi)存中,隨著對(duì)象的消失而消失乍炉,
而ObjectOutputStream可以將對(duì)象實(shí)體化
**Serializable接口沒(méi)有一個(gè)方法月培,也就是說(shuō)其是一個(gè)標(biāo)記接口。比如蓋章的豬肉才是安全的恩急。
**只有實(shí)現(xiàn)Serializable接口的子類才能被ObjectOutputStream系列化寫(xiě)入流,當(dāng)某個(gè)
類實(shí)現(xiàn)該接口后纪蜒,會(huì)被Java自動(dòng)分配UID號(hào)衷恭,以便編譯器識(shí)別,區(qū)分不同對(duì)象纯续。
**用ObjectOutputStream系列化的對(duì)象存儲(chǔ)到文件后随珠,該文件是亂碼,也就是不可讀的
的用ObjectInputStream讀取該類對(duì)象的屬性猬错。
**由于對(duì)象是有Java給對(duì)象分配相應(yīng)的UID號(hào)窗看,而UID號(hào)是根據(jù)對(duì)象的屬性不同而分配的。
當(dāng)一個(gè)類對(duì)象被系列化到文件后倦炒,如果該類改動(dòng)了對(duì)象的屬性显沈,比如將某個(gè)成員變量變成私有
則該對(duì)象再用ObjectInputStream讀取時(shí)會(huì)報(bào)異常,也就是說(shuō)該系列化到文件的對(duì)象不能再被使用了
那么逢唤,要想繼續(xù)使用屬性被改動(dòng)后的對(duì)象拉讯,我們可以自定義給對(duì)象分配UID號(hào),讓UID號(hào)不隨對(duì)象的屬性
變化而變化鳖藕。
自定義對(duì)象分配UID方法如下:
public static final long serialVersion UID = 43L;
**注意:
靜態(tài)不能被系列化魔慷,因?yàn)殪o態(tài)成員變量實(shí)在內(nèi)存的方法區(qū),而ObjectOutputStream只能
對(duì)對(duì)內(nèi)存里面的數(shù)據(jù)進(jìn)行系列化
被transient修飾的非靜態(tài)成員變量也不能被系列化
被系列化的對(duì)象存儲(chǔ)到文件中著恩,該文件是不可讀的院尔,所以該文件的擴(kuò)展名一般
不寫(xiě)成.txt,通常后綴名寫(xiě).object
**ObjectOutputStream
**ObjectInputStream
(3)管道流:
PipedInputStream
PipedOutputStream
(4)隨機(jī)訪問(wèn)文件:RandomAccess(重要:硖堋Q凇!)
**自身具備讀寫(xiě)方法(很牛逼裹驰!又可以讀又可以寫(xiě))
**通過(guò)skipByte(int x)和seek(int x)來(lái)達(dá)到隨機(jī)訪問(wèn)文件
**該類不是IO體系子類隧熙,而是直接繼承Object,但它是IO包中的成員幻林,因?yàn)樗邆渥x寫(xiě)方法
**該類內(nèi)部封裝了數(shù)組贞盯,而且通過(guò)指針對(duì)數(shù)組的元素進(jìn)行操作音念,可以通過(guò)getFilePoint獲取指針位置
同時(shí)可以通過(guò)seek改變指針位置
**該類完成讀寫(xiě)的原理是內(nèi)部封裝了字節(jié)輸入輸出流
**通過(guò)該類的構(gòu)造看出,該類只能操作文件躏敢,而且操作的文件只能有固定模式:
"r":只讀
"rw":讀寫(xiě)
"rws":
"red":
**構(gòu)造方法:
RandomAccessFile(File file, String mode)
創(chuàng)建從中讀取和向其中寫(xiě)入(可選)的隨機(jī)訪問(wèn)文件流闷愤,該文件由 File 參數(shù)指定。
RandomAccessFile(String name, String mode)
創(chuàng)建從中讀取和向其中寫(xiě)入(可選)的隨機(jī)訪問(wèn)文件流件余,該文件具有指定名稱讥脐。
**方法摘要:
void write(byte[] b)
將 b.length 個(gè)字節(jié)從指定 byte 數(shù)組寫(xiě)入到此文件,并從當(dāng)前文件指針開(kāi)始啼器。
void write(byte[] b, int off, int len)
將 len 個(gè)字節(jié)從指定 byte 數(shù)組寫(xiě)入到此文件旬渠,并從偏移量 off 處開(kāi)始。
void write(int b)
向此文件寫(xiě)入指定的字節(jié)端壳。
int read()
從此文件中讀取一個(gè)數(shù)據(jù)字節(jié)告丢。
int read(byte[] b)
將最多 b.length 個(gè)數(shù)據(jù)字節(jié)從此文件讀入 byte 數(shù)組。
int read(byte[] b, int off, int len)
將最多 len 個(gè)數(shù)據(jù)字節(jié)從此文件讀入 byte 數(shù)組损谦。
String readLine()
從此文件讀取文本的下一行岖免。
long getFilePointer()
返回此文件中的當(dāng)前偏移量。
long length()
返回此文件的長(zhǎng)度照捡。
void seek(long pos)
設(shè)置到此文件開(kāi)頭測(cè)量到的文件指針偏移量颅湘,在該位置發(fā)生下一個(gè)讀取或?qū)懭氩僮鳌?br> (4)操作基本數(shù)據(jù)類型的流對(duì)象:DateStream
(5)操作字節(jié)數(shù)組流:
ByteArrayInputStream
ByteArrayOutputStream
11、IO流轉(zhuǎn)換流的字符編碼
(1)字符流的出現(xiàn)為了方便操作字符栗精,更重要的是加入了編碼轉(zhuǎn)換
(2)通過(guò)子類轉(zhuǎn)換流來(lái)完成
InputStreamReander
OutputStreamWriter
(3)在兩個(gè)子類對(duì)象進(jìn)行構(gòu)造的時(shí)候可以加入編碼表
(4)編碼表:
將各個(gè)國(guó)家的文字用二進(jìn)制數(shù)字表示并一一對(duì)應(yīng)闯参,形成一張表,這就是編碼表
(5)常見(jiàn)的編碼表:
**ASCII:美國(guó)標(biāo)準(zhǔn)信息交換碼悲立,用一個(gè)字節(jié)的七位表示
**ISO8859-1:拉丁碼表赢赊,歐洲碼表,用一個(gè)字節(jié)的八位表示
**GB2312:中文編碼表级历,用兩個(gè)字節(jié)表示
**GBK:中文編碼表升級(jí)释移,融合錄入更多的中文字符,用兩個(gè)字節(jié)表示寥殖,為避免和老美重復(fù)
兩字節(jié)的最高位都是1玩讳,即漢字都是用負(fù)數(shù)表示
**Unicode:國(guó)際標(biāo)準(zhǔn)碼,融合了多種文字嚼贡,所有文字都用兩個(gè)字節(jié)表示
**UTF-8:用一個(gè)字節(jié)到三個(gè)字節(jié)表示熏纯。
注:Unicode能識(shí)別中文,UTF-8也能識(shí)別中文粤策,但兩種編碼表示一個(gè)漢字所用的字節(jié)數(shù)不同
Unicode用兩個(gè)字節(jié)樟澜,UTF-8用三個(gè)字節(jié),故涉及到編碼轉(zhuǎn)換。
(6)在流中涉及編碼表的轉(zhuǎn)換只有轉(zhuǎn)換流:
InputStreamReander
OutputStreamWriter
(7)代碼示例:
public static void write() throws IOException
{
OutputStreamWriter osw1 = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"GBK");
osw1.write("你好");
osw1.close();

        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("utf-8.txt"),"UTF-8");
        osw2.write("你好");
        osw2.close();
    }
    public static void read() throws IOException
    {
        InputStreamReader isr = new InputStreamReader(new FileInputStream("gbk.txt"),"GBK");
        byte[] buf = new byte[1024];
        int len = isr.read(buf);
        sop(new String(buf,0,len));
    }
(8)編碼解碼
    編碼:字符串變成字節(jié)數(shù)組:String-->getBytes()-->byte[]()
    解碼:字節(jié)數(shù)組變成字符串:byte[]-->new String(byte[],0,len)-->String
(9)代碼示例:
    public static void main(String[] args)
    {
        //編碼解碼1:默認(rèn)編碼
        String str1 = "你好";
        byte[] buf1 = str1.getBytes();//默認(rèn)解碼:Unicode秩贰,四個(gè)字節(jié)

        //編碼解碼2:指定編碼
        String str2 = "你好";
        byte[] buf2 = str2.getBytes("UTF-8");//指定解碼:UTF-8,六個(gè)字節(jié)

        
        //編碼解碼3:編碼正確解碼錯(cuò)誤
        String str3 = "你好";
        byte[] buf3 = str3.getBytes("GBK");//指定編碼:GBK,四個(gè)字節(jié)
        String str3 = new String(buf3,"ISO8859-1");//錯(cuò)誤解碼

        //編碼解碼4:錯(cuò)誤編碼正確解碼
        String str4 = "你好";
        byte[] buf4 = str4.getBytes("ISO8859-1");//錯(cuò)誤編碼
        String str4 = new String(buf4,"GBK");//正確解碼霹俺,讀不出來(lái)

        //編碼解碼5:編碼對(duì)了,但是解碼錯(cuò)誤了毒费,怎么辦呢丙唧?
        //此時(shí)可以將錯(cuò)誤的解碼再錯(cuò)編回去,載用正確編碼解碼
        String str5 = "你好";
        byte[] buf5 = str5.getBytes("GBK");//正確編碼
        String str6 = new String(buf5,"ISO8859-1");//錯(cuò)誤解碼觅玻,讀不出來(lái)
        byte[] buf6 = str6.getBytes("ISO8859-1");//再錯(cuò)誤編碼
        String str7 = new String(buf6,"GBK");//再正確解碼想际,這樣就可以讀出來(lái)了
    }

六、網(wǎng)絡(luò)編程:
1溪厘、網(wǎng)絡(luò)編程概述
(1)網(wǎng)絡(luò)模型
OSI參考模型
TCP/IP參考模型
(2)網(wǎng)絡(luò)通訊要素
IP地址
端口號(hào)
傳輸協(xié)議
(3)網(wǎng)絡(luò)通訊前提:
**找到對(duì)方IP
**數(shù)據(jù)要發(fā)送到指定端口胡本。為了標(biāo)示不同的應(yīng)用程序,所以給這些網(wǎng)絡(luò)應(yīng)用程序都用數(shù)字進(jìn)行標(biāo)示
畸悬。這個(gè)表示就叫端口打瘪。
**定義通信規(guī)則。這個(gè)規(guī)則稱為通信協(xié)議傻昙,國(guó)際組織定義了通用協(xié)議TCP/IP
(4)計(jì)算機(jī)網(wǎng)絡(luò):
是指將地理位置不同的具有獨(dú)立功能的多臺(tái)計(jì)算機(jī)及其外部設(shè)備,
通過(guò)通信線路連接起來(lái)彩扔,在網(wǎng)絡(luò)操作系統(tǒng)妆档,網(wǎng)絡(luò)管理軟件及網(wǎng)絡(luò)通信協(xié)議的管理和協(xié)調(diào)下,
實(shí)現(xiàn)資源共享和信息傳遞的計(jì)算機(jī)系統(tǒng)虫碉。
(5)IP地址:
IP地址 = 網(wǎng)絡(luò)號(hào)碼+主機(jī)地址

    A類IP地址:第一段號(hào)碼為網(wǎng)絡(luò)號(hào)碼贾惦,剩下的三段號(hào)碼為本地計(jì)算機(jī)的號(hào)碼
    B類IP地址:前二段號(hào)碼為網(wǎng)絡(luò)號(hào)碼,剩下的二段號(hào)碼為本地計(jì)算機(jī)的號(hào)碼
    C類IP地址:前三段號(hào)碼為網(wǎng)絡(luò)號(hào)碼敦捧,剩下的一段號(hào)碼為本地計(jì)算機(jī)的號(hào)碼

    特殊地址:
    127.0.0.1 回環(huán)地址,可用于測(cè)試本機(jī)的網(wǎng)絡(luò)是否有問(wèn)題. ping 127.0.0.1   
    ipconfig:查看本機(jī)IP地址
    xxx.xxx.xxx.0 網(wǎng)絡(luò)地址
    xxx.xxx.xxx.255 廣播地址

    A類  1.0.0.1---127.255.255.254   10.X.X.X是私有地址(私有地址就是在互聯(lián)網(wǎng)上不使用须板,而被用在局域網(wǎng)絡(luò)中的地址)                          (2)127.X.X.X是保留地址,用做循環(huán)測(cè)試用的兢卵。
    B類  128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址习瑰。169.254.X.X是保留地址。
    C類  192.0.0.1---223.255.255.254 192.168.X.X是私有地址
    D類  224.0.0.1---239.255.255.254     
    E類  240.0.0.1---247.255.255.254
(6)各種網(wǎng)絡(luò)分類方式
    A:按網(wǎng)絡(luò)覆蓋范圍劃分
      局域網(wǎng)(幾米至10公里以內(nèi))   城域網(wǎng)(10~100公里)   廣域網(wǎng)(幾百公里到幾千公里)   國(guó)際互聯(lián)網(wǎng)
    B:按網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)劃分
      總線型網(wǎng)絡(luò)   星形網(wǎng)絡(luò)   環(huán)型網(wǎng)絡(luò)   樹(shù)狀網(wǎng)絡(luò)   混合型網(wǎng)絡(luò)
    C:按傳輸介質(zhì)劃分
      有線網(wǎng)   無(wú)線網(wǎng)
    D:按網(wǎng)絡(luò)使用性質(zhì)劃分
      公用網(wǎng)   專用網(wǎng)
(7)虛擬專用網(wǎng)絡(luò)(Virtual Private Network 秽荤,簡(jiǎn)稱VPN)指的是在公用網(wǎng)絡(luò)上建立專用網(wǎng)絡(luò)的技術(shù)甜奄。
    其之所以稱為虛擬網(wǎng),主要是因?yàn)檎麄€(gè)VPN網(wǎng)絡(luò)的任意兩個(gè)節(jié)點(diǎn)之間的連接并沒(méi)有傳統(tǒng)專網(wǎng)
    所需的端到端的物理鏈路窃款,而是架構(gòu)在公用網(wǎng)絡(luò)服務(wù)商所提供的網(wǎng)絡(luò)平臺(tái)课兄,如Internet、
    ATM(異步傳輸模式〉晨继、Frame Relay (幀中繼)等之上的邏輯網(wǎng)絡(luò)烟阐,
    用戶數(shù)據(jù)在邏輯鏈路中傳輸。它涵蓋了跨共享網(wǎng)絡(luò)或公共網(wǎng)絡(luò)的封裝、
    加密和身份驗(yàn)證鏈接的專用網(wǎng)絡(luò)的擴(kuò)展蜒茄。VPN主要采用了隧道技術(shù)唉擂、加解密技術(shù)、
    密鑰管理技術(shù)和使用者與設(shè)備身份認(rèn)證技術(shù)扩淀。
(8)網(wǎng)絡(luò)模型:
    ****OSI模型
        應(yīng)用層
        表示層
        會(huì)話層
        傳輸層
        網(wǎng)絡(luò)層
        數(shù)據(jù)連接層
        物理層
    ****TCP/IP模型
        應(yīng)用層
        傳輸層
        網(wǎng)際層
        主機(jī)至網(wǎng)絡(luò)層

2楔敌、TCP和UDP
(1)UDP和TCP的區(qū)別:
UDP
將數(shù)據(jù)及源和目的封裝成數(shù)據(jù)包中,不需要建立連接
每個(gè)數(shù)據(jù)報(bào)的大小在限制在64k內(nèi)
因無(wú)連接驻谆,是不可靠協(xié)議
不需要建立連接卵凑,速度快
TCP
建立連接,形成傳輸數(shù)據(jù)的通道胜臊。
在連接中進(jìn)行大數(shù)據(jù)量傳輸
通過(guò)三次握手完成連接勺卢,是可靠協(xié)議
必須建立連接,效率會(huì)稍低
注:三次握手:
第一次:我問(wèn)你在么象对?
第二次:你回答在黑忱。
第三次:我反饋哦我知道你在赶盔。
3靶端、Socket(UDP傳輸)
**Socket就是為網(wǎng)絡(luò)服務(wù)提供的一種機(jī)制。
**通信的兩端都有Socket沉馆。
**網(wǎng)絡(luò)通信其實(shí)就是Socket間的通信冠绢。
**數(shù)據(jù)在兩個(gè)Socket間通過(guò)IO傳輸抚吠。
**玩Socket主要就是記住流程,代碼查文檔就行
(1)UDP傳輸:DatagramSocket與DatagramPacket
**發(fā)送端:
建立DatagramSocket服務(wù)弟胀;
提供數(shù)據(jù)楷力,并將數(shù)據(jù)封裝到字節(jié)數(shù)組中;
創(chuàng)建DatagramPacket數(shù)據(jù)包孵户,并把數(shù)據(jù)封裝到包中萧朝,同時(shí)指定IP和接收端口
通過(guò)Socket服務(wù),利用send方法將數(shù)據(jù)包發(fā)送出去夏哭;
關(guān)閉DatagramSocket和DatagramPacket服務(wù)检柬。
**接收端:
建立DatagramSocket服務(wù),并監(jiān)聽(tīng)一個(gè)端口竖配;
定義一個(gè)字節(jié)數(shù)組和一個(gè)數(shù)據(jù)包厕吉,同時(shí)將數(shù)組封裝進(jìn)數(shù)據(jù)包;
通過(guò)DatagramPacket的receive方法械念,將接收的數(shù)據(jù)存入定義好的數(shù)據(jù)包头朱;
通過(guò)DatagramPacke關(guān)閉t的方法,獲取發(fā)送數(shù)據(jù)包中的信息龄减;
關(guān)閉DatagramSocket和DatagramPacket服務(wù)项钮。
DatagramSocket與DatagramPacket方法摘要:
*****DatagramSocket
構(gòu)造方法:
DatagramSocket()
構(gòu)造數(shù)據(jù)報(bào)套接字并將其綁定到本地主機(jī)上任何可用的端口。
DatagramSocket(int port)
創(chuàng)建數(shù)據(jù)報(bào)套接字并將其綁定到本地主機(jī)上的指定端口。
DatagramSocket(int port, InetAddress laddr)
創(chuàng)建數(shù)據(jù)報(bào)套接字烁巫,將其綁定到指定的本地地址署隘。
方法摘要:
void close()
關(guān)閉此數(shù)據(jù)報(bào)套接字。
InetAddress getInetAddress()
返回此套接字連接的地址亚隙。
InetAddress getLocalAddress()
獲取套接字綁定的本地地址磁餐。
int getPort()
返回此套接字的端口。
void receive(DatagramPacket p)
從此套接字接收數(shù)據(jù)報(bào)包阿弃。
void send(DatagramPacket p)
從此套接字發(fā)送數(shù)據(jù)報(bào)包诊霹。
****DatagramPacket
構(gòu)造方法:
DatagramPacket(byte[] buf, int length)
構(gòu)造 DatagramPacket,用來(lái)接收長(zhǎng)度為 length 的數(shù)據(jù)包渣淳。
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
構(gòu)造數(shù)據(jù)報(bào)包脾还,用來(lái)將長(zhǎng)度為 length 的包發(fā)送到指定主機(jī)上的指定端口號(hào)。
InetAddress getAddress()
返回某臺(tái)機(jī)器的 IP 地址入愧,此數(shù)據(jù)報(bào)將要發(fā)往該機(jī)器或者是從該機(jī)器接收到的鄙漏。
byte[] getData()
返回?cái)?shù)據(jù)緩沖區(qū)。
int getLength()
返回將要發(fā)送或接收到的數(shù)據(jù)的長(zhǎng)度棺蛛。
int getPort()
返回某臺(tái)遠(yuǎn)程主機(jī)的端口號(hào)怔蚌,此數(shù)據(jù)報(bào)將要發(fā)往該主機(jī)或者是從該主機(jī)接收到的。
代碼示例:
****發(fā)送端:
class UDPSend
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds = new DatagramSocket();
byte[] buf = "這是UDP發(fā)送端".getBytes();
DatagramPacket dp = new DatagramPacket(
buf,buf.length,InetAddress.getByName("192.168.1.253"),10000);
ds.send(dp);
ds.close();
}
}
****接收端
class UDPRece
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds = new DatagramSocket(10000);
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);//將發(fā)送端發(fā)送的數(shù)據(jù)包接收到接收端的數(shù)據(jù)包中
String ip = dp.getAddress().getHosyAddress();//獲取發(fā)送端的ip
String data = new String(dp.getData(),0,dp.getLength());//獲取數(shù)據(jù)
int port = dp.getPort();//獲取發(fā)送端的端口號(hào)
sop(ip+":"+data+":"+port);
ds.close();
}
}
需求1:UDP鍵盤(pán)錄入數(shù)據(jù)旁赊,并發(fā)送給接收端
發(fā)送端:
class UDPSend
{
public static void main(String[] args) throws Exception
{

            DatagramSocket ds = new DatagramSocket();
            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
            String line = null;
            while((line = bufr.readLine())!=null)
            {
                if("886".equals(line))
                    break;
                byte[] buf = line.getBytes();
                DatagramPacket dp = new DatagramPacket(
                    buf,buf.length,InetAddress.getByName("192.168.1.253"),10000);
                ds.send(dp);
            }
            ds.close();
        }
            
    }
    接收端:
    class UDPRece
    {
        public static void main(String[] args) throws Exception
        {
            DatagramSocket ds = new DatagramSocket(10000);
            while(true)
            {
                byte[] buf = new byte[1024];
                DatagramPacket dp = new DatagramPacket(buf,buf.length);
                ds.receive(dp);//將發(fā)送端發(fā)送的數(shù)據(jù)包接收到接收端的數(shù)據(jù)包中
                String ip = dp.getAddress().getHosyAddress();//獲取發(fā)送端的ip
                String data = new String(dp.getData(),0,dp.getLength());//獲取數(shù)據(jù)
                int port = dp.getPort();//獲取發(fā)送端的端口號(hào)
                sop(ip+":"+data+":"+port);
                ds.close();
            }
        }
        
    }
    需求2:編寫(xiě)簡(jiǎn)單的聊天工具
    思路:
        使用多線程技術(shù)
    發(fā)送端:
    class UDPSend implements Runnable
    {
        private DatagramSocket ds;
        public UDPSend(){}
        public UDPSend(DatagramSocket ds)
        {
            this.ds=ds;
        }
        public void run()
        {
            try
            {
                BufferedReader bufr = new BufferedReader(
                            new InputStreamReader(System.in));
                String line = null;
                while((line = bufr.readLine())!=null)
                {
                    if("886".equals(line))
                        break;
                    byte[] buff = line.getBytes();
                    DatagramPacket dp = new DatagramPacket(
                    buf,buf.length,InetAddress.getByName("192.168.1.253"),10000);
                    ds.send(dp);
                }
            }
            catch(Exception e)
            {
                throw new RuntimeException("發(fā)送失敗");
            }
        }
    }
    接收端:
    class UDPRece implements Runnable
    {
        private DatagramSocket ds;
        public UDPSend(){}
        public UDPSend(DatagramSocket ds)
        {
            this.ds=ds;
        }
        public void run()
        {
            try
            {
                while(true)
                {   
                    byte[] buf = new byte[1024];
                    DatagramPacket dp = new DatagramPacket(buf,buf.length);
                    ds.receive(dp);//將發(fā)送端發(fā)送的數(shù)據(jù)包接收到接收端的數(shù)據(jù)包中
                    String ip = dp.getAddress().getHosyAddress();//獲取發(fā)送端的ip
                    String data = new String(dp.getData(),0,dp.getLength());//獲取數(shù)據(jù)
                    int port = dp.getPort();//獲取發(fā)送端的端口號(hào)
                    sop(ip+":"+data+":"+port);      
                }
            }
            catch(Exception e)
            {
                throw new RuntimeException("接收失敗");
            }
        }
    }
    測(cè)試類:
    class UDPTest
    {
        public static void main(String[] args)
        {
            DatagramSocket sendSocket = new DatagramSocket();
            DatagramSocket receSocket = new DatagramSocket(10000);

            new Thread(new UDPSend(sendSocket)).start();
            new Thread(new UDPRece(receSocket)).start();
        }
    }
(2)TCP傳輸
    Socket和ServerSocket
    建立客戶端和服務(wù)器端
    建立連接后桦踊,通過(guò)Socket中的IO流進(jìn)行數(shù)據(jù)的傳輸
    關(guān)閉socket
    同樣,客戶端與服務(wù)器端是兩個(gè)獨(dú)立的應(yīng)用程序彤恶。
    ****Socket
    **構(gòu)造方法:
    Socket() 
        通過(guò)系統(tǒng)默認(rèn)類型的 SocketImpl 創(chuàng)建未連接套接字
    Socket(InetAddress address, int port) 
        創(chuàng)建一個(gè)流套接字并將其連接到指定 IP 地址的指定端口號(hào)。
    Socket(String host, int port) 
        創(chuàng)建一個(gè)流套接字并將其連接到指定主機(jī)上的指定端口號(hào)鳄橘。
    **方法摘要:
    void close() 
        關(guān)閉此套接字声离。
    InetAddress getInetAddress() 
        返回套接字連接的地址。
    InputStream getInputStream() 
        返回此套接字的輸入流瘫怜。
    OutputStream getOutputStream() 
        返回此套接字的輸出流术徊。 
    int getPort() 
        返回此套接字連接到的遠(yuǎn)程端口。
    void shutdownInput() 
        此套接字的輸入流置于“流的末尾”鲸湃。 
    void shutdownOutput() 
        禁用此套接字的輸出流赠涮。 
    String toString() 
        將此套接字轉(zhuǎn)換為 String。
    ****ServerSocket
    **構(gòu)造方法:
    ServerSocket() 
        創(chuàng)建非綁定服務(wù)器套接字暗挑。 
    ServerSocket(int port) 
        創(chuàng)建綁定到特定端口的服務(wù)器套接字笋除。
    方法摘要:
    Socket accept() 
        偵聽(tīng)并接受到此套接字的連接。
    void close() 
        關(guān)閉此套接字炸裆。 
    InetAddress getInetAddress() 
        返回此服務(wù)器套接字的本地地址垃它。
    ****TCP傳輸流程:
    **客戶端:
    建立Socket服務(wù),并制定要連接的主機(jī)和端口;
    獲取Socket流中的輸出流OutputStream国拇,將數(shù)據(jù)寫(xiě)入流中洛史,通過(guò)網(wǎng)絡(luò)發(fā)送給服務(wù)端;
    獲取Socket流中的輸出流InputStream酱吝,獲取服務(wù)端的反饋信息也殖;
    關(guān)閉資源。
    **服務(wù)端:
    建立ServerSocket服務(wù)务热,并監(jiān)聽(tīng)一個(gè)端口忆嗜;
    通過(guò)ServerSocket服務(wù)的accept方法,獲取Socket服務(wù)對(duì)象陕习;
    使用客戶端對(duì)象的讀取流獲取客戶端發(fā)送過(guò)來(lái)的數(shù)據(jù)霎褐;
    通過(guò)客戶端對(duì)象的寫(xiě)入流反饋信息給客戶端;
    關(guān)閉資源该镣;
    ****代碼示例:
    客戶端:
    class TCPClient
    {
        public static void main(String[] args)
        {
            Socket s = new Socket("192.168.1.253",10000);
            OutputStream os = s.getOutputStream();
            out.write("這是TCP發(fā)送的數(shù)據(jù)".getBytes());
            s.close();
        }
    }
    服務(wù)端:
    class TCPServer
    {
        public static void main(String[] args)
        {
            ServerSocket ss = new ServerSocket(10000);
            Socket s = ss.accept();

            String ip = s.getInetAddress().getHostAddress();
            sop(ip);

            InputStream is = s.getInputStream();
            byte[] buf = new byte[1024];
            int len = is.read(buf);
            sop(new String(buf,0,len));
            s.close();
            ss.close();
        }
    }
    TCP需求1:客戶端給服務(wù)端發(fā)送數(shù)據(jù)冻璃,服務(wù)端接收到后反饋信息給客戶端
    客戶端:
    class TCPClient
    {
        public static void main(String[] args)
        {
            Socket s = new Socket("192.168.1.253",10000);
            OutputStream os = s.getOutputStream();
            out.write("這是TCP發(fā)送的數(shù)據(jù)".getBytes());
            
            InputStream is = s.getInputStream();
            byte[] buf = new byte[1024];
            int len = is.read(buf);
            sop(new String(buf,0,len));
            s.close();
        }
    }
    服務(wù)端:
    class TCPServer
    {
        public static void main(String[] args)
        {
            ServerSocket ss = new ServerSocket(10000);
            Socket s = ss.accept();

            String ip = s.getInetAddress().getHostAddress();
            sop(ip);

            InputStream is = s.getInputStream();
            byte[] buf = new byte[1024];
            int len = is.read(buf);
            sop(new String(buf,0,len));

            OutputStream os = s.getOutputStream();
            out.write("這是TCP發(fā)送的數(shù)據(jù)".getBytes());

            s.close();
            ss.close();
        }
    }
    TCP需求2:建立一個(gè)文本轉(zhuǎn)換服務(wù)端,客戶給服務(wù)端發(fā)送文本损合,服務(wù)端將數(shù)據(jù)轉(zhuǎn)換成大寫(xiě)后返回給客戶端
          當(dāng)客戶端輸入over時(shí)省艳,轉(zhuǎn)換結(jié)束
    客戶端:
    class TCPClient
    {
        public static void main(String[] args)
        {
            Socket s = new Socket("192.168.1.253",10000);
            BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
            BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(
                                    s.getOutputStream()));
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(
                                    s.getInputStream()));
            String line = null;
            while((line = bufr.readLine())!=null)
            {
                if("over".equals(line))
                    break;
                bufOut.write(line);
                bufOut.newLine();
                bufOut.flush();
                String retVal = bufIn.readLine();
                sop("server:"+retVal);
            }
            bufr.close();
            s.close();
        }
    }
    服務(wù)端:
    class TCPServer
    {
        public static void main(String[] args)
        {
            ServerSocket ss = new ServerSocket(10000);
            Socket s = ss.accept();

            String ip = s.getInetAddress().getHostAddress();
            sop(ip);
            
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(
                                    s.getInputStream()));
            BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(
                                    s.getOutputStream()));

            while((line = bufIn.readLine())!=null)
            {
                bufOut.write(line.toUpperCase());
                bufOut.newLine();
                bufOut.flush();
            }
            s.close();
            ss.close();
        }
    }
    **需求3:拷貝文件
    客戶端:
    class TCPClient
    {
        public static void main(String[] args)
        {
            Socket s = new Socket("192.168.1.253",10000);
            BufferedReader bufr = new BufferedReader(new FileReader("g:\\demo.txt"));
            PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
            String line = null;
            while((line = bufr.readLine())!=null)
            {
                pw.println();
            }
            s.shutDownOutput();
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(
                                    s.getInputStream()));
            String retVal = bufIn.readLine();
            sop(retVal);
            bufr.close();
            s.close();
        }
    }
    服務(wù)端:
    class TCPServer
    {
        public static void main(String[] args)
        {
            ServerSocket ss = new ServerSocket(10000);
            Socket s = ss.accept();

            String ip = s.getInetAddress().getHostAddress();
            sop(ip);
            
            BufferedReader bufIn = new BufferedReader(new InputStreamReader(
                                    s.getInputStream()));
            PrintWriter out = new PrintWriter(new FileWriter"copy.txt",true);
            String line =null;
            while((line = bufIn.readLine())!=null)
            {
                out.write(line);
            }
            PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
            pw.println("上傳成功");
            out.close();
            s.close();
            ss.close();
        }
    }
    需求4:上傳圖片
    客戶端:
    class TCPClient
    {
        public static void main(String[] args)
        {
            Socket s = new Socket("192.168.1.253",10000);
            FileInputStream fis = new FileInputStream("g:\\1.bmp");
            OutputStream out = s.getOutputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            while((len = bufr.read())!=-1)
            {
                out.write(buf,0,len);
            }
            s.shutDownOutput();

            InputStream in = s.getInputStream();
            byte[] bufIn = new byte[1024];
            int lenIn = in.read(bufIn);
            sop(new String(bufIn,0,lenIn);
            fis.close();
            s.close();
        }
    }
    服務(wù)端:
    class TCPServer
    {
        public static void main(String[] args)
        {
            ServerSocket ss = new ServerSocket(10000);
            Socket s = ss.accept();

            String ip = s.getInetAddress().getHostAddress();
            sop(ip);
            FileOutputStream fos = new FileOutputStream("g:\\copy.bmp");
            InputStream in = s.getInputStream();
            byte[] bufIn = new byte[1024];
            int lenIn = 0;
            while((lenIn=bufIn.read())!=-1)
            {
                fos.write(bufIn,0,lenIn)
            }

            OutputStream outIn = s.getOutputStream();
            outIn.write("上傳成功".getBytes());
            fos.close();
            s.close();
            ss.close();
        }
    }
    需求5:客戶端并發(fā)登陸
        客戶端通過(guò)鍵盤(pán)錄入用戶名,服務(wù)端對(duì)這個(gè)用戶名進(jìn)行校驗(yàn)
        如果用戶存在嫁审,在服務(wù)端現(xiàn)實(shí)xxx已登錄跋炕,并在客戶端現(xiàn)實(shí)歡迎xxx
        如果用戶不存在,在服務(wù)端現(xiàn)實(shí)xxx正在嘗試登陸律适,并在客戶端現(xiàn)實(shí)xxx用戶不存在
        最多登陸三次辐烂。
    校驗(yàn)端:
    class User implements Runnable
    (
        private Socket s;
        public User(){}
        public User(Socket s)
        {
            this.s=s;
        }
        public void run()
        {
            try
            {
                BufferedReader bufrIn = new BufferedReader(
                        new InputStream(s.getInputStream()))
                String name = bufrIn.readLine();
                if(name==null)
                {
                    sop("用戶名為空");
                    break;
                }
                BufferedReader bufr = new BufferedReader(
                        new FileReader("user.txt"));
                PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
                String line = null;
                boolean flag = false;
                while((line = bufr.reanLine())!=null)
                {
                    if(line.equals(name))
                    {
                        flag = true;
                        break;
                    }
                    if(flag)
                    {
                        sop(name+"已登陸");
                        pw.println("歡迎"+name);
                        break;
                    }
                    else
                    {
                        sop(name+"正嘗試登陸");
                        pw.println(name+"用戶不存在");
                    }

                }
                s.close();
            }
            catch(Exception e)
            {
                throw new RuntimeException("用戶校驗(yàn)失敗");
            }
        }
    )
    客戶端:
    class LoginClient
    {
        public static void main(String[] args)
        {
            Socket s = new Socket("192.168.1.253",10000);
            BufferedReader bufr = new BufferedReader(
                        new InputStreamReader(System.in)));
            PrintWriter out = new PrintWriter(s.getOutputStream(),true);
            BufferedReader bufIn = new BufferedReader(
                        new InputStreamReader(s.getInputStream()));
            for(int i=0;i<3;i++)
            {
                String line = bufr.readLine();
                if(line == null)
                {
                    sop("用戶名不能為空!");
                    break;
                }
                out.write(line);
                String retVal = bufIn.readLine();
                sop(retVal);    
            }
            bufr.close();
            s.close();
        }
    }
    服務(wù)端:
    class LoginServer
    {
        public static void main(String[] args)
        {
            ServerSocket ss = new ServerSocket(10000);
            while(true)
            {
                Socket s = ss.accept();
                new Thread(new User()).start();
            }
        }
    }
    得到各個(gè)字節(jié)碼對(duì)應(yīng)是實(shí)例對(duì)象(Class類型)
    ****類名.class,例如,System.class
    ****對(duì)象.getClass(),例如捂贿,new Date().getClass()
    ****Class.forName("類名"),例如纠修,Class.forName("java.util.Date");類加載器。若內(nèi)存中存在類的實(shí)例對(duì)象直接返回字節(jié)碼對(duì)象厂僧。如果不存在扣草,先加載類然后返回字節(jié)碼對(duì)象。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末颜屠,一起剝皮案震驚了整個(gè)濱河市辰妙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌甫窟,老刑警劉巖密浑,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異粗井,居然都是意外死亡肴掷,警方通過(guò)查閱死者的電腦和手機(jī)敬锐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)呆瞻,“玉大人台夺,你說(shuō)我怎么就攤上這事〕掌ⅲ” “怎么了颤介?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)赞赖。 經(jīng)常有香客問(wèn)我滚朵,道長(zhǎng),這世上最難降的妖魔是什么前域? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任辕近,我火速辦了婚禮,結(jié)果婚禮上匿垄,老公的妹妹穿的比我還像新娘移宅。我一直安慰自己,他們只是感情好椿疗,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布漏峰。 她就那樣靜靜地躺著,像睡著了一般届榄。 火紅的嫁衣襯著肌膚如雪浅乔。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天铝条,我揣著相機(jī)與錄音靖苇,去河邊找鬼。 笑死班缰,一個(gè)胖子當(dāng)著我的面吹牛贤壁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鲁捏,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼芯砸,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼萧芙!你這毒婦竟也來(lái)了给梅?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤双揪,失蹤者是張志新(化名)和其女友劉穎动羽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體渔期,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡运吓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年渴邦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拘哨。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谋梭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出倦青,到底是詐尸還是另有隱情瓮床,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布产镐,位于F島的核電站隘庄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏癣亚。R本人自食惡果不足惜丑掺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望述雾。 院中可真熱鬧街州,春花似錦、人聲如沸绰咽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)取募。三九已至琐谤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玩敏,已是汗流浹背斗忌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留旺聚,地道東北人织阳。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像砰粹,于是被迫代替她去往敵國(guó)和親唧躲。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法碱璃,類相關(guān)的語(yǔ)法弄痹,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法嵌器,異常的語(yǔ)法肛真,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,587評(píng)論 18 399
  • 一、Java 簡(jiǎn)介 Java是由Sun Microsystems公司于1995年5月推出的Java面向?qū)ο蟪绦蛟O(shè)計(jì)...
    子非魚(yú)_t_閱讀 4,154評(píng)論 1 44
  • 看到這張圖爽航,猛一想感覺(jué)此人不識(shí)時(shí)務(wù)蚓让,明擺著有自然的雨可以澆灌花朵乾忱,卻打把雨傘又自己提壺專門(mén)來(lái)澆水,感覺(jué)真是多此一舉...
    雨后青藍(lán)ll閱讀 888評(píng)論 0 0
  • 不 說(shuō) 故 事 寞肖, 只 講 道 理 提問(wèn) 最近有關(guān)性侵的新聞?wù)娴奶嗔耍娇丛娇膳滤ル纭N铱吹胶芏嗳司褪且驗(yàn)椴桓艺f(shuō)出來(lái)...
    愛(ài)晚睡閱讀 3,377評(píng)論 0 1
  • 文 / liuzesheng 我一直生活在江漢平原新蟆,長(zhǎng)江邊的沙市段。夏天右蕊,長(zhǎng)江流域漲水琼稻,我們一直關(guān)注著水患,三峽大...
    liuzesheng閱讀 1,411評(píng)論 48 41