前言
看了這本書(shū)兩遍岖沛,第一遍是很大略的看了一下,里面的代碼都沒(méi)怎么仔細(xì)研究淋袖,粗略的看。而第二遍屬于比較細(xì)致的看了锯梁,里面的代碼和練習(xí)題也都研究和敲了敲即碗。
首先這本書(shū)我覺(jué)得適合有一些項(xiàng)目經(jīng)驗(yàn)然后來(lái)學(xué)習(xí)思想的來(lái)看,因?yàn)闀?shū)里不會(huì)具體去將語(yǔ)法陌凳,所以不適合零基礎(chǔ)入門(mén)書(shū)剥懒。而且覺(jué)得這本書(shū)確實(shí)有助于加強(qiáng)對(duì)java語(yǔ)言的理解,特別是運(yùn)行機(jī)理合敦。
以下是我對(duì)這本書(shū)的做的一些筆記初橘,自己認(rèn)為比較重要的點(diǎn)。當(dāng)然因人而異充岛。從泛型開(kāi)始后面的章節(jié)沒(méi)有看保檐,因?yàn)殡y度較大,而且做項(xiàng)目中裸准,泛型和容器,I/O等等暫時(shí)涉及的不是很多赔硫,理解不是很透徹炒俱,等今后做過(guò)相應(yīng)項(xiàng)目再來(lái)研究一下。同事老程序員說(shuō)他們泛型那也看不太懂所以也不太建議我研究爪膊,當(dāng)然泛讀一下是很好的权悟。
思想
java編程思想更多的是告訴設(shè)計(jì)一樣語(yǔ)法的目的,為何設(shè)計(jì)這樣的語(yǔ)法推盛,然后再使用時(shí)候就會(huì)更清楚峦阁。什么時(shí)候用,應(yīng)該怎么用耘成,使用的目的榔昔。
自己想到一句話我覺(jué)得不錯(cuò):java中的對(duì)象成員和方法和人其實(shí)很相似:明確自己擁有什么驹闰,能干什么。
第一章:對(duì)象導(dǎo)論
- 將衍生累的對(duì)象當(dāng)作基礎(chǔ)類(lèi)的對(duì)象來(lái)對(duì)待撒会,把子類(lèi)的類(lèi)型當(dāng)作父類(lèi)類(lèi)型來(lái)處理的操作叫做upcasting向上轉(zhuǎn)型嘹朗。
- final,static诵肛,private和構(gòu)造方法是靜態(tài)綁定在創(chuàng)建類(lèi)是就被初始化屹培。而動(dòng)態(tài)綁定的典型發(fā)生在父類(lèi)和子類(lèi)的轉(zhuǎn)換聲明之下:比如:Parent p = new Children();而p.show()方法則先在子類(lèi)中找對(duì)應(yīng)的方法如果沒(méi)有就調(diào)用父類(lèi)方法。此為動(dòng)態(tài)綁定怔檩。
- 類(lèi)創(chuàng)建者褪秀,把類(lèi)中最內(nèi)部最脆弱的部分隱藏起來(lái),可以避免讓客戶端程序員使用而產(chǎn)生bug薛训。
- 所有類(lèi)都繼承自單一的基類(lèi)媒吗,這個(gè)類(lèi)是Object.叫做單根繼承。這對(duì)于垃圾的回收可以提高很大的效率许蓖。
- 用引用來(lái)操作對(duì)象蝴猪,引用相當(dāng)于遙控器,對(duì)象相當(dāng)于電視機(jī)膊爪。沒(méi)有電視機(jī)自阱,遙控器也可以獨(dú)立存在比如 String s;
- java的基本類(lèi)型數(shù)據(jù)直接存放到堆棧中。堆棧的存儲(chǔ)更高效米酬∨嫱悖基本類(lèi)型的所占存儲(chǔ)空間不變型是Java語(yǔ)言可移植的原因之一。
- 類(lèi)的成員變量先聲明赃额,什么時(shí)候用什么時(shí)候初始化加派,而局部變量要直接初始化然后用。
- boolean沒(méi)有明確的大小跳芳。僅定義能夠取true或者false.
- BigInteger可以存儲(chǔ)任意精度的int數(shù)據(jù)芍锦。BigDecimal可以存儲(chǔ)任意精度小數(shù)。
- java主要目標(biāo)之一是安全性飞盆。
- .net平臺(tái)相當(dāng)于JVM娄琉,JAVA程序的軟件平臺(tái)和JAVA類(lèi)庫(kù),C#和JAVA有很多類(lèi)似之處吓歇。
第二章:一切都是對(duì)象(Everything is an Object)
- String s 創(chuàng)建一個(gè)引用孽水,并不是對(duì)象。
- 基本類(lèi)型:不用new 來(lái)創(chuàng)建對(duì)象城看,而是創(chuàng)建一個(gè)并非引用的變量直接存儲(chǔ)到堆棧中女气。
- boolean并沒(méi)有明確說(shuō)明占幾個(gè)字節(jié)
- BigInteger和BigDecimal可以支持任意精度的整數(shù)和浮點(diǎn)數(shù)。
- 面向?qū)ο蟮某绦蛟O(shè)計(jì)通常簡(jiǎn)單的叫做“向?qū)ο蟀l(fā)送消息”测柠。
第三章:操作符(operators)
- 短路:一旦明確無(wú)誤的確定整個(gè)表達(dá)式的值就不需要再計(jì)算表達(dá)式余下的部分了
- +操作符連接不同的字符串炼鞠,一個(gè)表達(dá)式如果以一個(gè)字符串開(kāi)頭則后續(xù)所有操作數(shù)都會(huì)是字符串類(lèi)型缘滥。
- java中允許任何基本數(shù)據(jù)類(lèi)型轉(zhuǎn)換成別的基本數(shù)據(jù)類(lèi)型,但是布爾型不允許進(jìn)行轉(zhuǎn)換處理簇搅。
- “==”和“!=”比較的 都是對(duì)象的引用完域,基本類(lèi)型則表示值。
- 大多數(shù)java類(lèi)庫(kù)都實(shí)現(xiàn)了equals方法來(lái)比較對(duì)象的內(nèi)容而不是比較引用瘩将。
- 當(dāng)private修飾成員變量時(shí)吟税,任何外面的類(lèi)是無(wú)法訪問(wèn)到的。
- 關(guān)系操作符姿现,與或非肠仪,比較的是bool值,而且生成的也是bool值這一點(diǎn)與C語(yǔ)言不同备典。
- 當(dāng)以字符串開(kāi)頭時(shí)后面的輸出都會(huì)變成字符串形式异旧。
例:
int x = 0, y = 1, z = 2;
String s = "x, y, z ";
System.out.println(s + x + y + z); //x, y, z 012
System.out.println(x + y + z + " "+ x + y + z); //3 012
System.out.println(x + y + z + " " + s); //3 x, y, z - java中所有基本類(lèi)型可以進(jìn)行相互轉(zhuǎn)換,布爾型除外提佣,他不允許轉(zhuǎn)換處理吮蛹。類(lèi)之間可以進(jìn)行類(lèi)族之間的轉(zhuǎn)換。但是和其他類(lèi)型之間不行拌屏。
- 通常潮针,表達(dá)式中出現(xiàn)的最大數(shù)據(jù)類(lèi)型就是最后執(zhí)行的數(shù)據(jù)類(lèi)型。
- java數(shù)據(jù)類(lèi)型在所有機(jī)器中大小是相同的所以沒(méi)有sizeof()倚喂。
- java的Int數(shù)值溢出并不會(huì)報(bào)錯(cuò)每篷,所以請(qǐng)留意。
第四章:控制流程(Controlling Execution)
- java中沒(méi)有g(shù)oto端圈,而用標(biāo)簽來(lái)替代焦读。 使用標(biāo)簽的唯一理由就是因?yàn)橛醒h(huán)嵌套的存在,而且想從多層嵌套中break或continue
- 利用enum協(xié)調(diào)switch工作
- foreach 用來(lái)遍歷數(shù)組和Iterable對(duì)象
- swtich(n)
case value1: statement; break;
case value2: statement; break;
case value3: statement; break;
case value4: statement; break;
default : statement;
如果case后面沒(méi)有break則從執(zhí)行的case開(kāi)始后面的每個(gè)case都執(zhí)行舱权。
第五章 初始化與清理(Initialization and Cleanup)
- 初始化:給一個(gè)變量初始值矗晃。java盡力保證所有變量在使用前都能得到恰當(dāng)?shù)某跏蓟?/li>
- 類(lèi)中成員變量初始化總是在構(gòu)造器之前。但是成員對(duì)象的初始化可以在任意地方宴倍,也就是引用先初始化张症,而對(duì)象還沒(méi)有被初始化。
- 重載方法根據(jù)形參來(lái)確定啊楚,而不能通過(guò)返回值來(lái)確定吠冤。
- this只能在方法的內(nèi)部使用浑彰,用來(lái)表示調(diào)用到此方法的那個(gè)對(duì)象恭理。
- 除構(gòu)造器之外,禁止在其他方法中調(diào)用構(gòu)造器郭变。
- static方法就是沒(méi)有this的方法颜价。他無(wú)法應(yīng)用于局部變量涯保。
- 靜態(tài)順序,對(duì)象在第一次創(chuàng)建時(shí)候會(huì)調(diào)用static此后不便再調(diào)用周伦。請(qǐng)參照intialization/StaticIntialization.java很好的例子夕春。
- 在調(diào)用構(gòu)造器和方法之前會(huì)先對(duì)成員變量進(jìn)行初始化。
- 定義數(shù)組只需要在類(lèi)型后面加上方括號(hào)即可专挪。int[] a = new int[length];a是一個(gè)數(shù)組的引用及志。
- 應(yīng)盡量在創(chuàng)建數(shù)組引用時(shí)候?qū)λM(jìn)行初始化,如果忘記了創(chuàng)建對(duì)象寨腔,并試圖使用數(shù)組中的引用則會(huì)在運(yùn)行時(shí)產(chǎn)生異常速侈。
- 枚舉enum
public enum Spiciness {
NOT, MILD, MEDIUM, HOT, FLAMING
}
for(Spiciness s : Spiciness.values())
System.out.println(s + ", ordinal " + s.ordinal());
}
/* Output:
NOT, ordinal 0
MILD, ordinal 1
MEDIUM, ordinal 2
HOT, ordinal 3
FLAMING, ordinal 4
*///:~
Random rand = new Random(47);//獲得隨機(jī)數(shù),當(dāng)參數(shù)47時(shí)獲得最隨機(jī)的數(shù)迫卢,而如果不傳參數(shù)倚搬,則每次隨機(jī)數(shù)都不同,傳參每次返回一個(gè)固定的隨機(jī)數(shù)乾蛤。
System.out.println(rand.nextInt(150));
System.out.println(Math.random());
第六章:訪問(wèn)權(quán)限控制(Access Control)
- 編譯單元:每個(gè)以.java為結(jié)尾的文件每界,每個(gè)編譯單元只有一個(gè)public類(lèi),必須和編譯單元名稱相同家卖。一個(gè)編譯單元中其他的類(lèi)是無(wú)法被包之外的東西看到眨层。
- 所以public類(lèi)應(yīng)該是任何地方都可以訪問(wèn)的,如果在同一個(gè)包下則直接可以創(chuàng)建public類(lèi)的對(duì)象篡九,如果在不同包下則import導(dǎo)入包即可創(chuàng)建谐岁。
- jar包就是別人已經(jīng)寫(xiě)好的一些類(lèi),然后將這些類(lèi)進(jìn)行打包榛臼,單個(gè)壓縮文件里伊佃,就象Zip那樣,你可以將這些jar包引入你的項(xiàng)目中沛善,然后就可以直接import使用這些jar包中的類(lèi)和屬性以及方法航揉。然而,同Java中其他任何東西一樣金刁,JAR文件是跨平臺(tái)的帅涂,所以不必關(guān)心涉及具體平臺(tái)的問(wèn)題。
- public 是最強(qiáng)訪問(wèn)權(quán)限尤蛮,任何類(lèi)都可以訪問(wèn)媳友,不同包只要import相應(yīng)包即可,而默認(rèn)包訪問(wèn)權(quán)限只能在本包內(nèi)訪問(wèn)产捞,直接就可以使用醇锚,不需要import。
- 單例設(shè)計(jì)模式:只能創(chuàng)建一個(gè)該類(lèi)對(duì)象。構(gòu)造器為private焊唬。
class Soup2 {
private Soup2() {}
// (2) Create a static object and return a reference
// upon request.(The "Singleton" pattern):
private static Soup2 ps1 = new Soup2();
public static Soup2 access() {
return ps1;
}
public void f() {}
}
第七章:復(fù)用類(lèi)(Reusing Classes)
- 組合:當(dāng)一個(gè)新類(lèi)中引用另一個(gè)類(lèi)中的對(duì)象即組合恋昼。
public class SprinklerSystem {
private String valve1, valve2, valve3, valve4;
private WaterSource source = new WaterSource();//組合的使用
- 當(dāng)編譯器需要一個(gè)String而你卻只有一個(gè)對(duì)象時(shí),會(huì)調(diào)用類(lèi)中的toString()方法赶促。
System.out.println(sprinklers);
- 惰性初始化:創(chuàng)建對(duì)象的引用液肌,然后再要使用對(duì)象之前給引用初始化,這種方式不必為每個(gè)引用都創(chuàng)建對(duì)象而增加負(fù)擔(dān)鸥滨。
- 為了繼承:必須聲明新類(lèi)與舊類(lèi)相似嗦哆,也即extends,會(huì)自動(dòng)得到基類(lèi)中的所有域和方法婿滓。
- 為了繼承一般將所有的數(shù)據(jù)成員都指定為private吝秕,將所有的方法都指定為public。
- 當(dāng)創(chuàng)建子類(lèi)對(duì)象時(shí)空幻,會(huì)在子類(lèi)內(nèi)部創(chuàng)建一個(gè)父類(lèi)對(duì)象烁峭,java會(huì)自動(dòng)在子類(lèi)構(gòu)造器內(nèi)部插入對(duì)父類(lèi)構(gòu)造器的調(diào)用。
class BoardGame extends Game {
BoardGame(int i) {
super(i);
print("BoardGame constructor");
}
}
- 一個(gè)對(duì)象的創(chuàng)建秕铛,一次只能調(diào)用一個(gè)構(gòu)造器约郁。
- 引用不會(huì)被清理,清理的是失去引用的占用內(nèi)存的對(duì)象但两。
- @Override只能進(jìn)行方法覆蓋鬓梅,如果重載則會(huì)報(bào)錯(cuò),所以可以防止意外的對(duì)父類(lèi)方法進(jìn)行重載谨湘。
- 我們可以準(zhǔn)確的說(shuō)子類(lèi)是基類(lèi)的一種類(lèi)型绽快。
class Instrument {
public void play() {}
static void tune(Instrument i) {
// ...
i.play();
}
}
public class Wind extends Instrument {
public static void main(String[] args) {
Wind flute = new Wind();
Instrument.tune(flute); // Upcasting
}
}
//這里接收的Instrument可以是Instrument的所有導(dǎo)出類(lèi),把wind引用轉(zhuǎn)換為Instrument的動(dòng)作叫做向上轉(zhuǎn)型紧阔。他是安全的坊罢。
class Insect {
private static int x1 = printInit("static Insect.x1 initialized");
private int k = printInit("Insect.k initialized");
private int i = 9;
protected int j;
Insect() {
print("i = " + i + ", j = " + j);
j = 39;
}
private static void pringgt(){
System.out.println("靜態(tài)方法");
}
static int printInit(String s) {
print(s);
return 47;
}
}
public class Beetle extends Insect {
private static int x2 = printInit("static Beetle.x2 initialized");
private int k = printInit("Beetle.k initialized");
public Beetle() {
print("k = " + k);
print("j = " + j);
}
public static void main(String[] args) {
print("Beetle constructor");
Beetle b = new Beetle();
}
/* static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
Insect.k initialized
i = 9, j = 0
Beetle.k initialized
k = 47
j = 39
這段代碼注意以下幾點(diǎn):
1)編譯器會(huì)首先尋找Main方法,找到之后先執(zhí)行static成員變量擅耽。
然后執(zhí)行Main方法活孩,在創(chuàng)建對(duì)象的時(shí)候先執(zhí)行父類(lèi)的成員變量和構(gòu)造
然后執(zhí)行子類(lèi)的成員變量和構(gòu)造
當(dāng)靜態(tài)方法沒(méi)有被調(diào)用的時(shí)候是不執(zhí)行的。
*/
- 變量的定義在任何地方都是可行的乖仇,但是成員變量會(huì)自動(dòng)初始化賦值憾儒,而方法中的變量不會(huì)被初始化,如果直接使用會(huì)報(bào)錯(cuò)乃沙,但是定義是可行的起趾。
第八章:多態(tài)(Polymorphism)
- 面向?qū)ο笕筇匦裕悍庋b,繼承警儒,多態(tài)训裆。1)封裝:把數(shù)據(jù)操作這些數(shù)據(jù)的代碼封裝在類(lèi)中,并賦予訪問(wèn)權(quán)限。2)繼承某個(gè)類(lèi)型對(duì)象獲得另一個(gè)對(duì)象的屬性和方法缭保。
- 作用:消除類(lèi)型之間的耦合關(guān)系。
- 向上轉(zhuǎn)型:把某個(gè)對(duì)象的引用視為對(duì)其基類(lèi)的引用這樣的做法叫做向上轉(zhuǎn)型蝙茶。
- 對(duì)象數(shù)組的創(chuàng)建:
Animals [] an=new Animals[5];//這只是個(gè)對(duì)象類(lèi)型數(shù)組的聲明
用的時(shí)候需要
for(int i=0;i<5;i++)
an[i]=new Animals(); - 創(chuàng)建對(duì)象數(shù)組艺骂,多態(tài)中的運(yùn)用
Instrument[] orchestra = {
new Wind(),
new Percussion(),
new Stringed(),
new Brass(),
new Woodwind()
};
- 調(diào)用最后一個(gè)導(dǎo)出類(lèi)方法
class TwoMethods {
public int f1 = 4;
public void m1() {
System.out.println("Inside m1, calling m2");
m2();
}
public void m2() {
System.out.println("Inside m2");
}
public static String staticGet() {
return "Base staticGet()";
}
}
class Inherited extends TwoMethods {
public int f1 = 6;
@Override
public void m2() {
System.out.println("Inside Inherited.m2");
}
public static String staticGet() {
return "Derived staticGet()";
}
}
public class ex09 {
public static void main(String args[]) {
TwoMethods x = new Inherited();
x.m1();
System.out.println(x.f1);
System.out.println(sup.staticGet());
}
}
//Inside m1, calling m2
//Inside Inherited.m2
//4
//Base staticGet()
m1方法還是會(huì)調(diào)用子類(lèi)的m2方法,java總是會(huì)調(diào)用most-derived也即最子類(lèi)的覆蓋方法隆夯。
如果子類(lèi)和父類(lèi)有相同的成員變量钳恕,但是這不是多態(tài),多態(tài)針對(duì)方法蹄衷,這里調(diào)用的還是父類(lèi)的成員變量忧额。一般不會(huì)這么寫(xiě),因?yàn)槌蓡T變量一般用private.
靜態(tài)方法是跟類(lèi)關(guān)聯(lián)的也沒(méi)有多態(tài)性愧口。
- 在構(gòu)造器中避免調(diào)用其他方法睦番,如果有其他方法也應(yīng)該盡量設(shè)置成private的方法以防止被子類(lèi)覆蓋產(chǎn)生錯(cuò)誤。
- ClassCastException(類(lèi)型轉(zhuǎn)換異常)
第九章:接口(Interfaces)
- 抽象類(lèi):被抽象的方法是必須被重寫(xiě)的耍属,也就規(guī)定了必須要重寫(xiě)的公用方法托嚣,所以這應(yīng)該就是與普通類(lèi)繼承的區(qū)別。
- 接口被用來(lái)建立類(lèi)與類(lèi)之間的協(xié)議厚骗。
- 接口中的域和方法自動(dòng)為public權(quán)限示启,而接口本身可以是public或者默認(rèn)包訪問(wèn)權(quán)限。但是在類(lèi)的內(nèi)部中领舰,可以定義private的類(lèi)和接口夫嗓。
- 方法的覆蓋,返回值類(lèi)型必須和父類(lèi)方法相同或者是其返回類(lèi)型的子類(lèi)冲秽。
- 只能繼承一個(gè)類(lèi)舍咖,但可以實(shí)現(xiàn)多個(gè)接口
第十章:內(nèi)部類(lèi)(Inner Classes)
- 定義:把一個(gè)類(lèi)的定義放在另一個(gè)類(lèi)的定義的內(nèi)部,這就是內(nèi)部類(lèi)锉桑。
創(chuàng)建內(nèi)部類(lèi)對(duì)象 - 那什么時(shí)候用呢谎仲,具體用的時(shí)候應(yīng)該還是在一個(gè)類(lèi)只需要用一次的時(shí)候。無(wú)需重復(fù)使用創(chuàng)建對(duì)象的時(shí)候刨仑。
public class Parcel3 {
class Contents {
private int i = 11;
public int value() { return i; }
}
class Destination {
private String label;
Destination(String whereTo) { label = whereTo; }
String readLabel() { return label; }
}
public static void main(String[] args) {
Parcel3 p = new Parcel3();
// Must use instance of outer class
// to create an instance of the inner class:
Parcel3.Contents c = p.new Contents();
Parcel3.Destination d = p.new Destination("Tasmania");
}
class Parcel4 {
private class PContents implements Contents {
private int i = 11;
public int value() { return i; }
}
protected class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
public String readLabel() { return label; }
}
public Destination destination(String s) {
return new PDestination(s);
}
public Contents contents() {
return new PContents();
}
}
public class TestParcel {
public static void main(String[] args) {
Parcel4 p = new Parcel4();
Contents c = p.contents();
Destination d = p.destination("Tasmania");
// Illegal -- can't access private class:
//! Parcel4.PContents pc = p.new PContents();
}
} ///:~
- 使用內(nèi)部類(lèi)的好處:每個(gè)內(nèi)部類(lèi)都能獨(dú)自的繼承一個(gè)接口的實(shí)現(xiàn)郑诺,所以無(wú)論外圍類(lèi)是否繼承了某個(gè)類(lèi),對(duì)內(nèi)部類(lèi)都沒(méi)有影響杉武。所以內(nèi)部類(lèi)有效的實(shí)現(xiàn)了“多重繼承”辙诞。使得多重繼承方案變得完整。
- 所以內(nèi)部類(lèi)主要是為了實(shí)現(xiàn)多重繼承問(wèn)題轻抱。
- 匿名內(nèi)部類(lèi):
public class Parcel7 {
public Contents contents() {
return new Contents() { // Insert a class definition
private int i = 11;
public int value() { return i; }
}; // Semicolon required in this case
}
public static void main(String[] args) {
Parcel7 p = new Parcel7();
Contents c = p.contents();
}
} ///:~
//這段代碼表示“創(chuàng)建一個(gè)繼承自Contents的匿名類(lèi)的對(duì)象”
public class Parcel7b {
//內(nèi)部類(lèi)飞涂,實(shí)現(xiàn)Contents
class MyContents implements Contents {
private int i = 11;
public int value() { return i; }
}
//創(chuàng)建一個(gè)方法返回Contents類(lèi)型
public Contents contents() { return new MyContents(); }
public static void main(String[] args) {
Parcel7b p = new Parcel7b();
Contents c = p.contents();//調(diào)用此方法返回一個(gè)內(nèi)部類(lèi)的實(shí)現(xiàn)
}
} ///:~
//此端代碼為上一段代碼的完整形式
匿名內(nèi)部類(lèi)后面加上分號(hào)。
如果定義一個(gè)匿名內(nèi)部類(lèi),并且希望他使用一個(gè)在其外部定義的對(duì)象较店,那么編譯器會(huì)要求其參數(shù)引用是final 的士八。但是JDK1.8在不用final修飾的時(shí)候竟然也可以通過(guò)編譯,因?yàn)?.8把他默認(rèn)設(shè)置為final的了梁呈。
第十一章:持有對(duì)象(Holding Your Objects)-集合
- 集合只能存放引用類(lèi)型婚度,也就是集合存放的是引用,因?yàn)樾枰砑臃盒退圆荒艽鎯?chǔ)基本類(lèi)型官卡。而數(shù)組可以存儲(chǔ)基本類(lèi)型蝗茁,并且大小固定,而集合是大小可變寻咒。
- 通常保存基本類(lèi)型用數(shù)組哮翘,但是數(shù)組具有固定的尺寸,所以用容器保存對(duì)象毛秘,他會(huì)自動(dòng)調(diào)整尺寸饭寺。
- 向上轉(zhuǎn)型可以像作用與其他類(lèi)型一樣作用于泛型。
- 集合有兩個(gè)不同概念Collection:獨(dú)立元素序列叫挟,List必須按照插入的元素順序保存佩研,Set不能有重復(fù)元素,Queue霞揉。
- Map:一組鍵值對(duì)象旬薯。他們都是接口。像一個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)适秩。
- 通常創(chuàng)建對(duì)象時(shí)绊序,創(chuàng)建常用對(duì)象,而向上轉(zhuǎn)型為他的接口秽荞。
-迭代器(Iterator):是一個(gè)對(duì)象骤公,他的工作是遍歷并選擇序列中的對(duì)象,而不需要知道對(duì)象的底層結(jié)構(gòu)扬跋。威力:統(tǒng)一了對(duì)容器的訪問(wèn)方式阶捆。創(chuàng)建他的代價(jià)很小。
//不必知道具體的迭代器需要遍歷的序列類(lèi)型
public static void display(Iterator<Pet> it) {
while(it.hasNext()) {
Pet p = it.next();
System.out.print(p.id() + ":" + p + " ");
}
System.out.println();
}
public static void main(String[] args) {
ArrayList<Pet> pets = Pets.arrayList(8);
LinkedList<Pet> petsLL = new LinkedList<Pet>(pets);
HashSet<Pet> petsHS = new HashSet<Pet>(pets);
TreeSet<Pet> petsTS = new TreeSet<Pet>(pets);
display(pets.iterator());
display(petsLL.iterator());
display(petsHS.iterator());
display(petsTS.iterator());
}
- ListIterator是一個(gè)專門(mén)用于所有List的迭代器钦听,他可以雙向移動(dòng)洒试。而Iterator只能單向移動(dòng)。
List - ArrayList,隨機(jī)訪問(wèn)較快朴上,但是插入和移除元素比較慢垒棋。
- LinkedList在插入和刪除操作時(shí)較快,在隨機(jī)訪問(wèn)上較慢痪宰。他既實(shí)現(xiàn)了List又實(shí)現(xiàn)了Queue
- 棧:LIFO(后進(jìn)先出)叼架,像碗一樣畔裕。
Set
- Set,不保存重復(fù)元素乖订,常用來(lái)測(cè)試歸屬性扮饶。所以查找是Set中的最重要操作。
- HashSet專門(mén)對(duì)快速查找進(jìn)行了優(yōu)化乍构。用contains來(lái)測(cè)試set的歸屬性甜无。是最快的獲取元素的方式。
- TreeSet作為輸出有序的Set
Set set = new HashSet();
set.add("Bernadine");
set.add("Elizabeth");
set.add("Gene");
set.add("Elizabeth");
set.add("Clara");
System.out.println(set);
Set sortedSet = new TreeSet(set);//然后把集作為T(mén)reeSet來(lái)處理蜡吧。
- Queue隊(duì)列:可靠的將一個(gè)對(duì)象從一個(gè)區(qū)域傳輸?shù)搅硪粋€(gè)區(qū)域,他是先進(jìn)先出占键。LinkedList是隊(duì)列的一個(gè)實(shí)現(xiàn)昔善。
- HashMap也提供了最快的查找技術(shù),但沒(méi)有按照明確順序來(lái)保存元素畔乙,TreeMap按照比較結(jié)果的升序保存鍵君仆,而LinkedHashmap按插入順序保存鍵同時(shí)還保留了很快的查詢速度。
- 存入hashmap和hashset中的對(duì)象都是無(wú)序排列的牲距。也就是插入的順序和輸出的順序是不一致的返咱。
//entry用來(lái)迭代map
Map<String, String> map = new HashMap<String, String>();
map.put("111", "aaa");
map.put("222", "bbb");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
- 如要進(jìn)行大量的隨機(jī)訪問(wèn),使用ArrayList,如果要經(jīng)常從表中插入或刪除數(shù)據(jù)則用LinkedList.
第十二章:異常處理
第十三章:字符串
- 棧牍鞠,堆咖摹,常量池。棧:存放基本類(lèi)型變量和對(duì)象的引用难述。堆:存放new出來(lái)的對(duì)象中的成員變量萤晴。常量池:存放字符串敞亮和基本類(lèi)型常量。
- String類(lèi)型new產(chǎn)生的字符串胁后,首先去常量池中查找是否已經(jīng)存在店读,如果不存在則先在常量池中創(chuàng)建一個(gè)然后再在堆中創(chuàng)建一個(gè)對(duì)象。所以String s = new String(“xyz”);產(chǎn)生幾個(gè)對(duì)象攀芯?一個(gè)或兩個(gè)屯断,如果常量池中原來(lái)沒(méi)有”xyz”,就是兩個(gè)。
- 不可變string侣诺,String類(lèi)中每一個(gè)看起來(lái)會(huì)修改String值的方法實(shí)際上都是創(chuàng)建了一個(gè)全新的String對(duì)象殖演,以包含修改后的字符串內(nèi)容。
- java中僅有的兩個(gè)重載的操作符"+"和“+=”年鸳。
- 在拼接較少的情況下使用+方便剃氧,拼接的很多的情況一般也就在循環(huán)中,使用StringBuffer或StringBuilder來(lái)處理阻星。
String str = "hello,world!";
String result = "";
for (int i = 0; i < loopCount; i++) {
result += str;
}
//實(shí)際上是下面的代碼
String str = "hello,world!";
String result = "";
for (int i = 0; i < loopCount; i++) {
result = new StringBuilder(result).append(str).toString();
}
所以當(dāng)很多次進(jìn)行連接的時(shí)候朋鞍,會(huì)不停的創(chuàng)造StringBuilder對(duì)象從而影響性能已添,而這時(shí)如果使用一個(gè)StringBuilder來(lái)創(chuàng)建對(duì)象用append連接則只生成一個(gè)對(duì)象,很大的提高效率滥酥。
數(shù)組
- 數(shù)組是一種效率最高的存儲(chǔ)和隨機(jī)訪問(wèn)對(duì)象引用序列的方式更舞。
- 數(shù)組僅存的優(yōu)點(diǎn)就是效率。
- 基本類(lèi)型數(shù)組與對(duì)象數(shù)組使用時(shí)相同的坎吻,唯一區(qū)別是基本類(lèi)型數(shù)組保存的是值缆蝉,而對(duì)象數(shù)組保存的是引用。
- length只是數(shù)組能容納多少元素瘦真,并不是實(shí)際保存元素的個(gè)數(shù)刊头。
- 數(shù)組拷貝System.arraycopy();