CoreJava全套詳細筆記心血放出資料_第1頁
CoreJava全套詳細筆記心血放出資料_第2頁
CoreJava全套詳細筆記心血放出資料_第3頁
CoreJava全套詳細筆記心血放出資料_第4頁
CoreJava全套詳細筆記心血放出資料_第5頁
已閱讀5頁,還剩47頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

目錄TOC\o"1-5"\h\z\o"CurrentDocument"原碼、反碼、補碼 5\o"CurrentDocument"原碼 5\o"CurrentDocument"反碼 5\o"CurrentDocument"補碼 5負數(shù)的補碼轉(zhuǎn)換為十進制數(shù) 6\o"CurrentDocument"char 6\o"CurrentDocument"運算符 6移位運算符 6位運算符 7邏輯運算符 7\o"CurrentDocument"流程控制 7\o"CurrentDocument"switch 7\o"CurrentDocument"break和continue 8\o"CurrentDocument"方法 8\o"CurrentDocument"構(gòu)造方法 8\o"CurrentDocument"方法重載 8\o"CurrentDocument"this 9\o"CurrentDocument"繼承 9\o"CurrentDocument"super 9\o"CurrentDocument"多態(tài)(polymorphism) 10\o"CurrentDocument"instanceof 10\o"CurrentDocument"static 11\o"CurrentDocument"final 11\o"CurrentDocument"abstract 12\o"CurrentDocument"類的加載 12觸發(fā)類加載的幾種情況 12類加載的順序 12\o"CurrentDocument"接口(interface) 13\o"CurrentDocument"訪問控制 14\o"CurrentDocument"Object類 15\o"CurrentDocument"clone() 15\o"CurrentDocument"對象克隆過程 15\o"CurrentDocument"淺復(fù)制和深復(fù)制概念 16\o"CurrentDocument"finalize() 16\o"CurrentDocument"equals(Objectobj) 16\o"CurrentDocument"toString() 16\o"CurrentDocument"String類及對象池 16\o"CurrentDocument"Stringa="hello"; 17\o"CurrentDocument"Stringc=newString("hello"); 17\o"CurrentDocument"StringBuffer和StringBuilder 17\o"CurrentDocument"主方法參數(shù) 18\o"CurrentDocument"方法的可變長參數(shù) 18\o"CurrentDocument"包裝類 18\o"CurrentDocument"Number 19\o"CurrentDocument"自動封箱 /自動解封(Autoboxing/Unboxing) 19\o"CurrentDocument"對象池 19\o"CurrentDocument"內(nèi)部類 20\o"CurrentDocument"意義 20\o"CurrentDocument"四種形式的內(nèi)部類 20\o"CurrentDocument"靜態(tài)內(nèi)部類 20\o"CurrentDocument"成員內(nèi)部類 21\o"CurrentDocument"局部內(nèi)部類 22\o"CurrentDocument"匿名內(nèi)部類 22內(nèi)部類的應(yīng)用 24\o"CurrentDocument"集合框架(CollectionFramework) 24\o"CurrentDocument"Iterator接口和Iterable接口 25\o"CurrentDocument"Connection接口和 Connections類 25\o"CurrentDocument"java.util.Collection 25\o"CurrentDocument"java.util.Collections 25\o"CurrentDocument"List(列表)接口 25\o"CurrentDocument"ArrayList 26\o"CurrentDocument"LinkedList 26\o"CurrentDocument"Vector 26\o"CurrentDocument"214 Set(集合)接口 26\o"CurrentDocument"HashSet 27\o"CurrentDocument"TreeSet 29排序的兩種辦法 29\o"CurrentDocument"java.Iang.Comparable(可比較的) 29\o"CurrentDocument"java.util.Comparator( 比較器) 30\o"CurrentDocument"Map 30\o"CurrentDocument"HashMap 30\o"CurrentDocument"Hashtable 31\o"CurrentDocument"Hashtable下的子類 Properties類 31\o"CurrentDocument"SortedMap接口下的 TreeMap類 31\o"CurrentDocument"泛型(Generic) 32\o"CurrentDocument"泛型特點 32\o"CurrentDocument"通配符 32\o"CurrentDocument"上限通配符: 32\o"CurrentDocument"下限通配符 33\o"CurrentDocument"總結(jié): 33\o"CurrentDocument"運用 34\o"CurrentDocument"異常 34異常處理基礎(chǔ) 34異常的類繼承結(jié)構(gòu) 34常見的未檢查異常 35throw 35\o"CurrentDocument"自定義異常類 36\o"CurrentDocument"反射(Reflection) 37反射需要用到的類 37\o"CurrentDocument"java.lang.Class 37\o"CurrentDocument"java.lang.reflect.Field 38\o"CurrentDocument"java.lang.Package 38\o"CurrentDocument"java.lang.relect.Modifier 38\o"CurrentDocument"java.lang.reflect.Mothed 38\o"CurrentDocument"java.lang.reflect.Array 38\o"CurrentDocument"java.lang.reflect.Constructor 38242 三種獲得某個類的Class對象的方法 38\o"CurrentDocument"Classc=Class.forName(”類名”); 38\o"CurrentDocument"Classc=類名.class; 39\o"CurrentDocument"Classc=對象名.getClass(); 39所能探查出來的類的特征 39通過反射生成一個類的實例 39\o"CurrentDocument"第一種方法 40\o"CurrentDocument"第二種方法 40\o"CurrentDocument"File 40\o"CurrentDocument"構(gòu)造方法 40\o"CurrentDocument"重點方法 41\o"CurrentDocument"目錄 42\o"CurrentDocument"流 42\o"CurrentDocument"字節(jié)流 42\o"CurrentDocument"字符流 44\o"CurrentDocument"節(jié)點流(NodeStream): 45過濾流(FilterStream) 45\o"CurrentDocument"ObjectInputStream和ObjectOutputStream 46\o"CurrentDocument"字節(jié)流轉(zhuǎn)化成字符流的橋轉(zhuǎn)換器 48文本文件和二進制文件 50\o"CurrentDocument"線程 50概念與原理 50操作系統(tǒng)中線程和進程的概念 50Java中的線程 51Java中的線程模型 51一些常見問題 51線程狀態(tài)的轉(zhuǎn)換 52線程的七種狀態(tài) 52阻止線程執(zhí)行 54線程的同步與鎖 55同步和鎖定 55靜態(tài)方法同步 60如果線程不能獲得鎖會怎么樣 60何時需要同步 61線程安全類 61線程死鎖 62線程同步小結(jié) 63線程的交互 64線程交互的基礎(chǔ)知識 64多個線程在等待一個對象鎖時候使用notifyAll() 66守護線程(后臺服務(wù)線程) 67并發(fā)協(xié)作-生產(chǎn)者消費者模型 68volatile關(guān)鍵字 68網(wǎng)絡(luò)編程 69TCPSocket編程 69ServerSocket 70Socket 70UDPSocket編程 71DatagramSocket 71DatagramPacket 71原碼、反碼、補碼原碼將最高位作為符號位(以0代表正,1代表負),其余各位代表數(shù)值本身的絕對值(以二進制表示)。為了簡單起見,我們用1個字節(jié)來表示一個整數(shù):+7的原碼為:00000111-7的原碼為:10000111問題:+0的原碼為:00000000-0的原碼為:10000000反碼一個數(shù)如果為正,則它的反碼與原碼相同;一個數(shù)如果為負,則符號位為1,其余各位是對原碼取反。為了簡單起見,我們用1個字節(jié)來表示一個整數(shù):+7的反碼為:00000111-7的反碼為:11111000問題:+0的反碼為:-0的反碼為:補碼利用溢出,我們可以將減法變成加法。對于十進制數(shù),如果從9得到結(jié)果5,可以用減法:9-4=5;因為4+6=10,我們將6作為4的補數(shù),將上式的減法改寫為加法: 9+6=15;去掉高位1(也就是減去10),得到結(jié)果5。對于16進制數(shù),如果從C得到結(jié)果5,可以用減法:C-7=5;因為7+9=16,我們將9作為7的補數(shù),將上式的減法改寫為加法: C+9=15;去掉高位1(也就是減去16),得到結(jié)果5。在計算機中,如果我們用1個字節(jié)表示一個數(shù),一個字節(jié)有 8位,超過8位就進1,在內(nèi)存中情況為:100000000,進位1被丟棄。一個數(shù)如果為正,則它的原碼、反碼、補碼相同;一個數(shù)如果為負,則符號位為 1,其余各位是對原碼取反,然后整個數(shù)加1。為了簡單起見,我們用1個字節(jié)來表示一個整數(shù)。+7的補碼為:00000111-7的補碼為:1111100114負數(shù)的補碼轉(zhuǎn)換為十進制數(shù)a、 先對各位取反;b、 將其轉(zhuǎn)換為十進制數(shù);c、 加上負號,再減去1。例如:11111010,最高位為1,是負數(shù),先對各位取反得00000101,轉(zhuǎn)換為十進制數(shù)得5,加上負號得-5,再減1得-6。charchar類型(2字節(jié))用于表示Unicode編碼的字符單元;char類型用于表示單個字符,通常用來表示字符常量。例如:'A'是編碼為65所對應(yīng)的字符常量。Unicode編碼單元可以表示為十六進制值,其范圍從 \u0000到\uffff。除了可以米用轉(zhuǎn)義序列符\u表示Unicode代碼單兀的編碼之外,還有一些用于表示特殊字符的轉(zhuǎn)義序列符。如:轉(zhuǎn)義序列名稱Unicode值\b退格(Backspace)\u0008\t制表(Tab)\u0009\n換行(Linefeed)\u000a\r回車\u000d雙引號(Doublequote)\u0022單引號(Singlequote)\u0027\\反斜杠(Backslash)\u005c盡管char不是整數(shù),但在許多情況中你可以對它們進行運算操作就好像他們是整數(shù)一樣,這允許你可以將2個字符相加,或?qū)σ粋€字符變量值進行增量操作。運算符移位運算符只能針對二進制數(shù)據(jù)(整數(shù))<<左移,左移一位相當于原來的數(shù)乘二,大于 32位的話高出的位就不要了,如果移動的位數(shù)大于32的話java會自動把這個位數(shù)變?yōu)檫@個數(shù)對 32求余的值;>>右移,右移一位相當于除2取整,兩位相當于連續(xù)除2取整而不是除4取整,看正數(shù)還是負數(shù),正數(shù)右移的話高位補 0,負數(shù)的話補1;>>>無符號右移(算數(shù)右移),不考慮符號位,移進來的都補 0。32位運算符&按位與,兩個數(shù)按位與,全部轉(zhuǎn)換成二進制后按位比較, 全為1才是1,其它是0,返回一個新的整數(shù);|按位或,兩個數(shù)按位或,全部轉(zhuǎn)換成二進制后按位比較, 全為0才是0,其它是1,返回一個新的整數(shù);A按位異或,兩個數(shù)的二進制位數(shù)比較, 相同結(jié)果為0,相異結(jié)果為1;~按位求反,把一個數(shù)二進制的每一位都反過來。邏輯運算符&&短路與,兩邊如果左邊是假的話就不再判斷右邊的,直接返回假;II短路或,兩邊如果有一個為真的就不再判斷右邊的,直接返回真;&與,不管怎樣兩邊都會判斷,都為真才返回真;I或,不管怎樣兩邊都會判斷,都為假才返回假。流程控制switcha、 switch后括號中的值必須是int,byte,char,short,枚舉類型的變量之一,其它類型的就不行了;b、 每個case后面的值必須是不相等的,而且 必須是常量;c、 如果每個case冒號后面的語句執(zhí)行完后沒有 break,還會繼續(xù)執(zhí)行后面 case里的語句,所以在每個case的語句結(jié)束后加一個break;d、 多個case可以可并到一起,表示或的關(guān)系;e、 default代表如果和所有case后的值都不匹配,就執(zhí)行這里的語句。無論 default寫哪都是最后執(zhí)行的。publicclassGrade{publicstaticvoidmain(String[]args){Scannersca=newScanner(System.in);System.out.println( ”請輸入一個百分數(shù): ”);ints=sca.nextInt();if(s<0||s>100){System.out.println( "ERRORDATA:S");System.exit(0); //退出這個程序}switch(s/10){case10:case9:System.out.println("A");breakcase8:System.out.println("B");breakcase7:System.out.println("C");breakcase6:System.out.println("D");breakdefault:System.out.println("E");break}42break和continuea、break退出當前的循環(huán)體,在嵌套循環(huán)中,只退出當前的 一層循環(huán);b、 continue結(jié)束當前本次循環(huán),繼續(xù)進行下一輪的循環(huán)。可以說,只是本次忽略循環(huán)內(nèi)后面的語句;c、 continue只能在循環(huán)體內(nèi)用;d、break可以用在任意代碼塊中,表示退出當前程序塊 (配合標簽使用,很好用)。方法構(gòu)造方法每次在創(chuàng)建實例變量,對類中的所有變量都要初始化是很乏味的。 如果在一個對象最初被創(chuàng)建時就把對它的設(shè)置做好, 那樣的話,程序?qū)⒏唵尾⑶腋喢鳌?因為對初始化的要求是共同的,Java允許對象在他們被創(chuàng)造時初始化自己。 這種自動的初始化是通過使用構(gòu)造方法來完成的。構(gòu)造方法在對象創(chuàng)建時初始化。一旦定義了構(gòu)造方法,在對象創(chuàng)建后,在 new運算符完成前,構(gòu)造方法立即自動調(diào)用。 構(gòu)造方法看起來有點奇怪, 因為它沒有任何返回值,即使是void型的值也不返回。這是因為一個類的構(gòu)造方法內(nèi)隱藏的類型是它自己類的類型。構(gòu)造方法的任務(wù)就是初始化一個對象的內(nèi)部狀態(tài),以便使創(chuàng)建的實例變量能夠完全初始化,可以被對象馬上使用。方法重載在Java中,同一個類中的2個或2個以上的方法可以有同一個名字,只要它們的參數(shù)聲明不同即可。在這種情況下,該方法就被稱為重載( overloaded)。當一個重載方法被調(diào)用時,Java用參數(shù)的類型和(或)數(shù)量來表明實際調(diào)用的重載方法的版本。因此,每個重載方法的參數(shù)的類型和(或)數(shù)量必須是不同的。當一個重載的方法被調(diào)用時,Java在調(diào)用方法的參數(shù)和方法的自變量之間尋找匹配。 但是,這種匹配并不總是精確的。 在一些情況下,Java的自動類型轉(zhuǎn)換也適用于重載方法的自變量。例如:classOverloadDemo{voidtest(doublea){System.out.println("Insidetest(double)a:"+a);}}classOverload{publicstaticvoidmain(Stringargs[]){OverloadDemoob=newOverloadDemo();inti=88;ob.test(i);}}OverloadDemo的這個版本沒有定義test(int)。因此當在Overload內(nèi)帶整數(shù)參數(shù)調(diào)用test()時,找不到和它匹配的方法。但是,Java可以自動地將整數(shù)轉(zhuǎn)換為 double型,這種轉(zhuǎn)換就可以解決這個問題。因此,在 test(int)找不到以后,Java將i擴大到double型,然后調(diào)用test(double)。當然,如果定義了 test(int),當然先調(diào)用test(int)而不會調(diào)用test(double)。只有在找不到精確匹配時,Java的自動轉(zhuǎn)換才會起作用。thisthis等價于當前對象,調(diào)用當前對象的屬性或方法就用 this.屬性名,或this.方法名()。當前對象:指誰在調(diào)用當前這個方法和屬性, 誰就是當前對象。在定義類的時候是不存在當前對象的。在局部變量與外部變量同名的時候, 為了區(qū)分,就要在外部變量的前面加一個 this來表示這個變量是類的全局變量。繼承盡管子類包括超類的所有成員,它不能訪問超類中被聲明成 private的成員。子類的對象可以調(diào)用父類的一切公有的變量和方法,也可以擴展自己新的屬性和方法,但是新擴展的部分父類的對象是無法調(diào)用的。super在子類的構(gòu)造方法中調(diào)用父類的構(gòu)造方法,并且 super要放在第一行,不能與this一起用,主要用為在構(gòu)造子類的時候給父類中定義的變量賦值:a、 任何子類的構(gòu)造方法都會調(diào)用父類的構(gòu)造方法:因為調(diào)用構(gòu)造方法和創(chuàng)建一個對象是綁在一起的,而一個子類對象的一部分可以看做是父類對象,所以當創(chuàng)建一個子類對象時一定是先創(chuàng)建一個父類的對象,再在父類對象的基礎(chǔ)上擴展(extends)成一個子類對象。注意:自始至終只創(chuàng)建了一個對象,因為創(chuàng)建的那一個子類對象的一部分是父類對象(上帝想創(chuàng)造一個科學(xué)家,肯定是先創(chuàng)造一個人,在人的基礎(chǔ)上進行教育培訓(xùn)等,最終變成一個科學(xué)家,而最初的人和最后的科學(xué)家其實是一個對象);b、任何子類的構(gòu)造方法的第一行必須是 this(...)或super(...)的調(diào)用,如果程序員不寫,則系統(tǒng)會隱含的調(diào)用 super(),也就是說子類無論如何都會調(diào)用父類的構(gòu)造方法,沒寫就調(diào)用父類的無參構(gòu)造方法;c、子類構(gòu)造方法的第一行只能出現(xiàn)this(...),super(...)這兩種情況,無論怎么調(diào)用,最終總能找到父類構(gòu)造方法,否則造成死循環(huán)。因為如果子類的某個構(gòu)造方法的第一行出現(xiàn)this(...),此時系統(tǒng)不會加上缺省的 super(…)那么this(...)會調(diào)用子類的其他構(gòu)造方法,所以子類的構(gòu)造方法之間開始調(diào)用,如果子類的所有的構(gòu)造方法的第一行全都是this(...)那便構(gòu)成了一個死循環(huán)。多態(tài)(polymorphism)a、 對象的多態(tài):一個對象多種形態(tài)。方法的重載和覆蓋就是方法多態(tài)的一種體現(xiàn);b、對象多態(tài)的基礎(chǔ):子類對象可以當作父類對象來看,例如: Animala=newBird();c、 多態(tài)定理:如果我們把子類對象當作父類對象來看,那么就只能訪問父類中已有定義的屬性和方法(不能訪問子類擴展的屬性和方法)。如果子類覆蓋了父類的方法,再把子類對象當作父類對象去調(diào)用該方法時,調(diào)用的是子類覆蓋后的方法(對象的行為不可能因為你把它當作什么來看而改變);d、 Animala=newBird()左邊是編譯時類型:在代碼編譯過程中,編譯器把這個對象當作什么來看?(父類對象)右邊是運行時類型:在代碼執(zhí)行過程中,JVM把這個對象當作什么看?(子類對象)。左邊是主觀認為(我們把a當作什么看?),右邊是客觀存在(a實際是什么)。當你把鳥當動物看時,你知道它是動物,但你不知道它是鳥,所以你知道它會走會吃,但你不知道它會唱歌(相當于編譯器把它當Animal),所以你不會試圖去調(diào)用它的唱歌的方法,因為你根本就不知道它會唱歌。當你調(diào)用 move()方法時,它會flying,因為它本質(zhì)上還是個鳥,不會因為你把它當作動物而不會飛用走的路。instanceof當發(fā)生多層次復(fù)雜的繼承機構(gòu)時,往往使程序員自己都搞不清楚最后這個對象到底是什么了,這時就需要提供一個方法來判斷一下了。判斷一個對象是不是某一個類型的實例,看這個對象能不能作為這個對象實例來看(看這個對象運行時的類型,即看這個對象的客觀存在是什么) 。static描述整體特征而不是個體特征的屬性時,用靜態(tài)修飾符;有時你希望定義一個類成員,使它的使用完全獨立于該類的任何對象。通常情況下,類成員必須通過它的類的對象訪問,但是可以創(chuàng)建這樣一個成員,它能夠被它自己使用,而不必引用特定的實例。成員的聲明前面加上關(guān)鍵字static就能創(chuàng)建這樣的成員。如果一個成員被聲明為static,它就能夠在它的類的任何對象創(chuàng)建之前被訪問,而不必引用任何對象。你可以將方法和變量都聲明為static,static成員的最常見的例子是main(),因為在程序開始執(zhí)行時必須調(diào)用main(),所以它被聲明為static。聲明為static的變量實質(zhì)上就是全局變量,當聲明一個對象時,并不產(chǎn)生static變量的拷貝,而是該類所有的實例變量共用同一個static變量。?聲明為static的方法有以下幾條限制a、 它們僅能調(diào)用其他的static方法;b、 它們只能訪問static數(shù)據(jù);c、 它們不能以任何方式引用this或super。?靜態(tài)變量和非靜態(tài)變量(實例變量)的差別a、 空間分配時機:靜態(tài)變量是在類加載的時候分配空間,非靜態(tài)對象是在生成對象的時候分配空間;b、 空間分配方式:不管有多少對象靜態(tài)變量只有一份(所有對象共享),非靜態(tài)變量有多少對象就分配多少個空間;c、 訪問方式:靜態(tài)變量是:類名.屬性,比如Animal.COUNT;非靜態(tài)變量:對象名.屬性,比如。?靜態(tài)方法和非靜態(tài)方法的區(qū)別a、 靜態(tài)方法是通過類名來調(diào)用,非靜態(tài)方法是通過對象來調(diào)用;b、 靜態(tài)方法中不能訪問本類的非靜態(tài)成員,但非靜態(tài)方法可以訪問靜態(tài)成員;c、 靜態(tài)方法不存在多態(tài)特性,也就是靜態(tài)方法無法被子類覆蓋,父類對象調(diào)用此方法還是父類的。?靜態(tài)代碼塊a、 靜態(tài)代碼塊會在類被加載時被系統(tǒng)自動執(zhí)行;b、 一般可以在靜態(tài)代碼塊中給靜態(tài)屬性賦值;c、 類的靜態(tài)代碼塊只能有一個。finala、 聲明為final的變量在實例中不占用內(nèi)存;b、 一個final變量實質(zhì)上是一個常數(shù);c、 修飾屬性時屬性不可變,并且屬性在聲明的時候必須初始化,或者在構(gòu)造方法中初始化一般與static一起用,一旦定義了,就不能再變了;d、 修飾方法時方法不能被覆蓋;e、 修飾類是類不能被繼承,表示最終的類,不能有子類;f、修飾局部變量時局部變量不可變(常量)。abstracta、 用來修飾類和方法;b、 修飾類的話表示這個類是個抽象類,抽象類不能被實例化(生成對象) ;c、 修飾方法的話表示這個方法是個抽象方法,抽象方法沒有方法體;d、 如果一個類包含有一個抽象方法,那么這個類必須是抽象類;e、 如果一個類不包含抽象方法,那么該類也可以被定義成抽象類;f、 抽象類不能被實例化,但卻可以定義引用;g、 抽象類一般需要實現(xiàn)--定義一個子類,并實現(xiàn)抽象方法;h、 抽象類也是有構(gòu)造方法的,因為需要被子類調(diào)用;i、 子類必須實現(xiàn)父類的抽象方法;j、 abstract和final不能共同修飾一個類或方法;k、 例如:定義一個Animal類,就可以定義成抽象類,move()方法可以定義成抽象方法,當具體的子類繼承Animal時,再覆蓋move()方法,鳥飛,魚游 類的加載觸發(fā)類加載的幾種情況a、 調(diào)用靜態(tài)成員時,會加載靜態(tài)成員真正所在的類及其父類;b、 通過子類調(diào)用父類的靜態(tài)成員時,只會加載父類而不會加載子類;c、 第一次new對象的時候加載(第二次再new同一個類時,不需再加載);d、 加載子類會先加載父類(覆蓋父類方法時所拋出的異常不能超過父類定義的范圍)e、 如果靜態(tài)屬性有final修飾時,則不會加載,當成常量使用,例如:publicstaticfinalinta=123;但是如果上面的等式右值改成表達式(且該表達式在編譯時不能確定其值)時則會加載類,例如:publicstaticfinalinta=math.PIf、 如果訪問的是類的公開靜態(tài)常量,那么如果編譯器在編譯的時候能確定這個常量的值,就不會被加載,如果編譯時不能確定其值的話,則運行時加載。類加載的順序?加載靜態(tài)成員/代碼塊先遞歸地加載父類的靜態(tài)成員/代碼塊(Object的最先),再依次加載到本類的靜態(tài)成員。同一個類里的靜態(tài)成員/代碼塊,按寫代碼的順序加載。如果其間調(diào)用靜態(tài)方法,則調(diào)用時會先運行靜態(tài)方法,再繼續(xù)加載。同一個類里調(diào)用靜態(tài)方法時,可以不理會寫代碼的順序。調(diào)用父類的靜態(tài)成員,可以像調(diào)用自己的一樣,但調(diào)用其子類的靜態(tài)成員,必須使用 子類名.成員名”來調(diào)用。?加載非靜態(tài)成員/代碼塊(實例塊在創(chuàng)建對象時才會被加載,而靜態(tài)成員在不創(chuàng)建對象時可以加載)先遞歸地加載父類的非靜態(tài)成員 /代碼塊(Object的最先),再依次加載到本類的非靜態(tài)成員。同一個類里的非靜態(tài)成員 /代碼塊,按寫代碼的順序加載。同一個類里調(diào)用方法時,可以不理會寫代碼的順序。 但調(diào)用屬性時,必須注意加載順序。一般編譯不通過,如果能在加載前調(diào)用,值為默認初始值(如:null或者0)。調(diào)用父類的非靜態(tài)成員(private除外),也可以像調(diào)用自己的一樣。?調(diào)用構(gòu)造方法先遞歸地調(diào)用父類的構(gòu)造方法(Object的最先),默認調(diào)用父類空參的,也可在第一行寫明調(diào)用父類某個帶參的。 再依次到本類的構(gòu)造方法, 構(gòu)造方法內(nèi),也可在第一行寫明調(diào)用某個本類其它的構(gòu)造方法。注意:如果加載時遇到override的成員,可看作是所需創(chuàng)建的類型賦值給當前類型。其調(diào)用按多態(tài)用法:只有非靜態(tài)方法有多態(tài) ;而靜態(tài)方法、靜態(tài)屬性、非靜態(tài)屬性都沒有多態(tài)。假設(shè)子類override父類的所有成員,包括靜態(tài)成員、非靜態(tài)屬性和非靜態(tài)方法。由于構(gòu)造子類時會先構(gòu)造父類, 而構(gòu)造父類時,其所用的靜態(tài)成員和非靜態(tài)屬性是父類的, 但非靜態(tài)方法卻是子類的,由于構(gòu)造父類時,子類并未加載,如果此時所調(diào)用的非靜態(tài)方法里有成員,則這個成員是子類的,且非靜態(tài)屬性是默認初始值的。1、加載父類靜態(tài)成員/代碼塊2、加載子類靜態(tài)成員/代碼塊旦3、 加載父類非靜態(tài)成員/代碼塊—旦—4、 加載父類構(gòu)造方法5、 加載子類非靜態(tài)成員/代碼塊6、 加載子類構(gòu)造方法接口(interface)a、 接口可以通過運用關(guān)鍵字extends被其他接口繼承;b、當一個類實現(xiàn)一個繼承了另一個接口的接口時, 它必須實現(xiàn)接口繼承鏈表中定義的所有方法;c、 是一種抽象的數(shù)據(jù)類型,特殊的抽象類;d、接口中的所有方法都是抽象方法,就算不寫系統(tǒng)也會自動加上 abstract,所以一般就省去不寫了;e、 接口中所有的屬性都是finalstatic的(靜態(tài)常量),就算不寫系統(tǒng)也會自動加上,所以一般可以省去不寫了;f、接口也不能被實例化,但可以定義的接口的引用;g、接口沒有構(gòu)造方法,接口的實現(xiàn)類在生成對象時不會調(diào)用接口的構(gòu)造方法, 類的子類在生成對象時一定要調(diào)用父類的構(gòu)造方法 (所以子類長的像父類,卻不像接口);h、 一個類只能繼承一個父類,但是可以實現(xiàn)多個接口,用逗號隔開;i、 接口之間可以多繼承;j、 接口=標準:把服務(wù)的使用者和服務(wù)的提供者分開,降低系統(tǒng)的耦合,有效的提高軟件的可擴展性和可維護性;k、接口聲明中可以聲明變量, 它們一般是final和static型的,意思是它們的值不能通過實現(xiàn)類而改變,它們還必須以常量值初始化,如果接口本身定義成 public,所有方法和變量都是public的。訪問控制訪問控制(accesscontrol)訪問指示符(accessspecifier)Private成員UU的成員ProlePublic^員同一類中可見是是是是同一個包中對子類町見同一個包中對非子類可見否是是不同包巾對子矣否不同的包中對卓子類可見習(xí)否否是staticfinalabstractpublicprotected默認private頂層類NYYYNYN屬性YYNYNYY方法YYYYYYY局部變量NYNNNNN成員式內(nèi)部類YYYYYYY局部式內(nèi)部類NYYNNNNObject類構(gòu)造方法只有唯一的一個,并且無參。clone()protectedObjectcione()throwsCioneNotSupportedException創(chuàng)建并返回一個當前對象的拷貝,得到和當前對象一模一樣的對象。clone()方法滿足:a、 對任何的對象x,都有x.clone()!=x;克隆對象與原對象不是同一個對象了;b、 對任何的對象x,都有x.clone().getClass==x.getClass();克隆對象與原對象的類型一樣;c、 如果對象x的equals方法定義恰當,那么x.clone().equals(x)應(yīng)該成立。對象克隆過程? 要讓這個類實現(xiàn)java.lang.Cloneable接口Cloneable接口,指示Object.clone()方法可以合法地對該類實例進行按字段復(fù)制。如果在沒有實現(xiàn)Cloneable接口的實例上調(diào)用Object的clone方法,則會導(dǎo)致拋出CioneNotSupportedException異常。按照慣例,實現(xiàn)此接口的類應(yīng)該使用公共方法重寫 Object.clone(它是受保護的)。注意,此接口不包含clone方法。因此,因為某個對象實現(xiàn)了此接口就克隆它是不可能的。即使clone方法是反射性調(diào)用的,也無法保證它將獲得成功。Cloneable接口沒有任何方法, 像Cloneable這樣的接口叫做標記接口, 即標記這個類的實例可以調(diào)用clone方法,只是起到一個標記的作用。?覆蓋Object中的clone()方法,并將訪問權(quán)限改為 publicclone();方法的訪問修飾符是 protected,這意味著,在子類中直接去super.clone();是可以的,但是如果想在第三方類中去生成一個子類對象后再取調(diào)用 cione()時就不可以了,所以這時就得在子類中去覆蓋 Object的clone方法,并將訪問控制修飾符改為 public。如果只是希望淺復(fù)制,那么使用這樣的代碼就可以完成publicObjectcione()throwsCioneNotSupportedException{returnsuper.clone();}這段代碼表示,覆蓋Object中的clone方法,將訪問控制修飾符改為 public,然后再去調(diào)用Object的clone方法。clone方法有具體的實現(xiàn)步驟代碼, 這叫做是實現(xiàn)方法。因為clone方法涉及到底層數(shù)據(jù)的訪問, 一般的程序員是沒有辦法寫出這些代碼的, 所以用這樣的一個簡單的步驟就可以達到 clone的目的了。14.12淺復(fù)制和深復(fù)制概念?淺復(fù)制(淺克隆)被復(fù)制對象的所有變量都含有原來的對象的相同的值,而所有的對其他對象的引用仍然指向原來的對象。換言之,淺復(fù)制僅僅復(fù)制所考慮的對象,而不是復(fù)制它所引用的對象。?深復(fù)制(深克隆)被復(fù)制對象的所有變量都含有與原來的對象相同的值,除去那些引用其他對象的變量。那些引用其他對象的變量將指向被復(fù)制過的新對象, 而不再是原有的那些被引用的對象。 換言之,深復(fù)制把要復(fù)制的對象所引用的對象都復(fù)制了一遍。例如:一個Student對象包含ID,姓名,Teacher等屬性。其中ID為基本類型,姓名為String類型,Teacher為一個Teacher對象。淺復(fù)制只復(fù)制一個新的ID,而姓名和Teacher只復(fù)制地址。即,復(fù)制后的新對象姓名和Teacher仍然指向原先的Stuent的姓名和Teacher。而深復(fù)制會連同姓名和Teacher也同樣復(fù)制出來,并且與原對象的地址不同,指向不同的對象。finalize。a、構(gòu)造方法負責對象創(chuàng)建后的初始化, finalize方法負責對象消亡時的資源釋放;b、 finalize方法被垃圾收集器自動調(diào)用,而垃圾收集器有可能根本不執(zhí)行,所以沒有辦法保證finalize方法一定執(zhí)行。equals(Objectobj)下面是Object中的equals方法源碼:publicbooleanequals(Objectobj){|return(this==obj);}toString()返回該對象的字符串表示。通常, toString方法會返回一個"以文本方式表示”此對象的字符串。結(jié)果應(yīng)是一個簡明但易于讀懂的信息表達式。建議所有子類都重寫此方法。Object類的toString方法返回一個字符串,該字符串由類名(對象是該類的一個實例)、at標記符“@”和此對象哈希碼的無符號十六進制表示組成。換句話說,該方法返回一個字符串,它的值等于:getClass().getName()+@'+Integer.toHexString(hashCode())String類及對象池在JDK5.0里面,Java虛擬機在啟動的時候會實例化 9個對象池,這9個對象池分別用對象池的存在是為了避免頻繁的創(chuàng)建和銷毀對象而影響系統(tǒng)性能。 對象池是獨立于??臻g和堆空間的,保存著指向一些對象的首地址。Stringa="hello";首先把hello這個對象創(chuàng)建出來,并保存在堆中。然后對象池會保存一個指向 hello的首地址。如果a是某個方法內(nèi)的局部變量,那么也會在棧中將 hello的首地址保存在a中。如果a的地址值被賦為null,也就是a不再指向hello了,此時hello并沒有成為垃圾,因為對象池中始終保存了 hello的首地址指向hello。而對象池中的那些地址值,程序員是不能直接管理的,那是由 JVM才能直接管理的。下次如果需要Stringb="hello";創(chuàng)建"hello"對象,那么b會去對象池中找那些地址值, 如果找到了指向hello對象的地址,那么會將這個地址直接賦給 b。如果沒有與之匹配的,才會創(chuàng)建新的對象,并同樣將這個對象的首地址保存在對象池中。Stringc=newString("hello");系統(tǒng)會直接在堆空間中創(chuàng)建一個新的 hello對象,而不會去對象池中找,而且這樣創(chuàng)建的新的hello對象也不會保存在對象池去。注意注意:Strings=newString("hello");直接只有這條語句的時候,這里的 hello作為一個參數(shù)傳給String,而此時沒有hello這個對象,那么:首先會創(chuàng)建一個hello對象,并且將這個hello對象的首地址保存在對象池中,然后將這個hello對象作為參數(shù)傳給String,此時又new了一個新hello對象,而s中保存的是新的hello對象的首地址。所以只有這條語句的時候,實際上是創(chuàng)建了兩個 hello對象。StringBuffer和StringBuilder當我們需要對字符串頻繁的進行修改時, 最好不要用String類,因為那會產(chǎn)生很多垃圾,降低系統(tǒng)效率。在java.lang包下,有兩個StringBuffer和StringBuilder類,是更好的選擇。因為用它們new出來的字符出對象是可以更改的,而且會在原字符串的基礎(chǔ)上進行更改,而不會向String那樣創(chuàng)建新的字符串對象,所以避免了垃圾的產(chǎn)生。而StringBuffer和StringBuilder的唯一區(qū)別是:StringBuffer是線程安全的(Thread-safe)字符序列;StringBuider是線程不安全的字符序列。主要關(guān)注點:一是構(gòu)造方法,二是眾多重載的append(追加)和insert(插入)方法。publicclassStringBufferTest{publicstaticvoidmain(String[]args){StringBuffers=newStringBuffer();for(charc='A';c<='Z';c++){s.append(c);}System.out.println(s.toString());}}主方法參數(shù)java類名命令后面還可以給一些主方法的參數(shù),這些參數(shù)都被系統(tǒng)當作字符串放到main方法聲明的參數(shù)String[]args中,如果輸入多個參數(shù)的話就以空格為分隔符依次把每個參數(shù)放入args數(shù)組。如果不傳參數(shù)的話 args就是一個0個元素的數(shù)組。在eclipse中給主方法傳參數(shù):右鍵runasrunconfigurationsMainclass要是現(xiàn)在要運行的類,如果不是就要search找到arguments在上面的欄中就是給main方法傳的參數(shù),填上參數(shù)applyRun。在把這些參數(shù)傳給主方法之前, JVM會先對這些參數(shù)做一個包裝,把它們先包裝成一個字符串數(shù)組之后再傳給主方法。所以主方法的參數(shù)是 String[]args。方法的可變長參數(shù)其實當我們把不同長度的參數(shù)傳給方法時, 編譯器會對這些參數(shù)做一個包裝, 把它們包裝成一個數(shù)組之后再傳給方法,所以方法得到的還是一個數(shù)組。所以方法的可變長參數(shù)實際上是數(shù)組的一種特殊的表現(xiàn)形式。在定義方法的時候知道要傳的參數(shù)的類型, 但是參數(shù)的數(shù)量不固定的時候就用可變長參數(shù),可變長參數(shù)類型的寫法,例如: publicstaticvoidm(String...strs){}上面的參數(shù)類型在String后面多了...,這樣在調(diào)用方法傳參數(shù)的時候就可以傳多個參數(shù)或者一個參數(shù),也可以不傳參數(shù),但參數(shù)必須都為String類型的,如果要傳其它類型的時候在定義的時候改成其它類型,然后在類型后面加上 …就可以了。如何使用這些參數(shù):在方法中此參數(shù)是被當作數(shù)組類訪問的, 調(diào)用length就可以知道有多少參數(shù)傳進來,這種參數(shù)既能接受單個元素做參數(shù), 也可以接受數(shù)組作參數(shù)。也就是說可變長的參數(shù)類型兼容了數(shù)組參數(shù)類型,但是數(shù)組參數(shù)類型不能兼容可變長參數(shù)類型。使用可變長參數(shù)的規(guī)定:a、一個方法只能有一個可變長參數(shù),而且該參數(shù)必須是這個方法的最后一個參數(shù);b、可變長參數(shù)的方法只有在必須的時候才被調(diào)用, 也就是說,如果有不可變長參數(shù)的方法可以匹配,這種調(diào)用,那么系統(tǒng)會優(yōu)先選擇不可變長參數(shù)的方法的調(diào)用。包裝類Java使用簡單的類型,例如整型(int)和字符(char)。這些數(shù)據(jù)類型不是對象層次結(jié)構(gòu)的組成部分。它們通過值傳遞給方法而不能直接通過引用傳遞。 而且,也沒有辦法使兩種方法對整型(int)引用同一實例(sameinstanee)。有時需要對這些簡單的類型建立對象表達式。為了滿足這種需要,Java提供了與每一個簡單類型相應(yīng)的類。 本質(zhì)上,這些類在類中包裝(wrap)簡單類型。因此,它們通常被稱作類型包裝器( wrappers)。Number抽象類Number是BigDecimal、Biglnteger、Byte、Double、Float、Integer、Long和Short類的超類。Number的子類必須提供將表示的數(shù)值轉(zhuǎn)換為 byte、double、float、int、long和short的方法。抽象類Number定義了一個由包裝數(shù)字類型字節(jié)型(byte),短整型(short),整型(int),長整型(long),浮點型(float)和雙精度型(double)的類實現(xiàn)的超類。Number有返回上面不同數(shù)字格式的對象值的抽象方法。也就是, doubleValue()方法返回雙精度(double)值,floatValue()方法返回浮點(float)值等。自動圭寸箱/自動解圭寸(Autoboxing/Unboxing)在JDK1.5之前要獲得一個基本類型的對象比如 Integer只能用Integeri=newInteger(5)或者Integeri=Integer.valueOf(5)但在JDK1.5以后可以直接寫成Integeri=5;在這里虛擬機默認的為這個基本數(shù)據(jù)類型進行了包裝,以上面的第二種形式即:Integeri=Integer.valueOf(5);這種自動的包裝叫做自動封箱。另外還可以自動解封,比如:inta=i;這種形式就相當與inta=i.intValue();對象池除了字符串類型的對象會創(chuàng)建對象池, 八種基本類型的包裝類也會創(chuàng)建對象池。 但是這些包裝類new出來也只創(chuàng)建一個對象,Integer的對象池在啟動的時候就創(chuàng)建好了,范圍是-128~127之間,所以在這之間的數(shù)字對象都不會再創(chuàng)建新對象,超出的部分都會再創(chuàng)建新對象,不會在從對象池中拿。例如:Integeri1=5;//對象池中拿Integeri2=5;//i1==i2Integeri3=newInteger(5);//重新創(chuàng)建一個對象,所以 i2!=i3同理String的另一個特點,Integer對象的值也是不可改變的。所以頻繁的創(chuàng)建修改Integer對象也會生成很多垃圾。但是 Integer的根本是int基本類型,所以直接用int就可以了。像:for(inti=0;i<1000000;i++)而不用復(fù)雜的把i定義成Integer。publicclass IntegerTest{publicstaticvoidmain(String[]args){Integeri1=5;Integeri2=Integer. valueOf(5);Integeri3=newInteger(5);System.out.println(i1==i2);System.out.println(i1==i3);System.out.println(IIIntegeri4=250;Integeri5=Integer.valueOfIntegeri6=newInteger(250);System.out.println(i4==i5);System.out.println(i4==i6);//上面兩種形式都是從對象池中拿對象,所以它們相等(250);內(nèi)部類意義a、 更小的層次的封裝,把一個類隱藏在另外一個類的內(nèi)部;b、 能方便的在內(nèi)部類中訪問外部類的私有成員。四種形式的內(nèi)部類a、靜態(tài)內(nèi)部類、成員內(nèi)部類統(tǒng)稱成員式內(nèi)部類, 與成員變量、成員方法處于一個級別;b、 靜態(tài)內(nèi)部類就像靜態(tài)成員一樣,成員內(nèi)部類就像實例成員一樣;c、 局部內(nèi)部類、匿名內(nèi)部類統(tǒng)稱局部式內(nèi)部類,與方法內(nèi)的局部變量處于一個級別。靜態(tài)內(nèi)部類a、 不能訪問外部類的非靜態(tài)成員;b、在外面訪問此類的話就用:外部類名 .內(nèi)部類名;c、 創(chuàng)建了一個靜態(tài)內(nèi)部類對象語法:外部類名?內(nèi)部類名變量=new外部類名?內(nèi)部類構(gòu)造函數(shù)()例如:OuterA.InnerAinn=newOuterA.InnerA();d、靜態(tài)內(nèi)部類和外部類對象實際上沒什么關(guān)系的, 靜態(tài)內(nèi)部類與外部類的關(guān)系類似于寄居關(guān)系,寄居只是借外部類的殼把自己隱藏起來, 在生成內(nèi)部類對象時不需要外部類對象。2022.成員內(nèi)部類a、 可以訪問外部類的靜態(tài)和非靜態(tài)成員;b、生成一個成員內(nèi)部類對象要復(fù)雜的多, 生成一個成員內(nèi)部類對象之前必須先生成一個外部類對象:外部類名.內(nèi)部類名對象名=外部類對象.new內(nèi)部類名();例如:OuterAout=newOuterA();OuterA.InnerBinnb=out.newInnerB();c、成員內(nèi)部類與外部類的關(guān)系類似于寄生關(guān)系, 在生成內(nèi)部類對象時必須要有外部類對象,一個內(nèi)部類對象一定對應(yīng)著一個外部類對象。如何選擇用靜態(tài)內(nèi)部類或成員內(nèi)部類a、 如果外部類怎么變化都不影響內(nèi)部類的話,那么推薦用靜態(tài)內(nèi)部類;b、 如果操作內(nèi)部類的改變能影響外部類,那么推薦使用成員內(nèi)部類。publicclass InnerClassTest1{publicstaticvoidmain(String[]args){//這里的OuterA就好像是InnerA外面的一層包一樣,這和調(diào)用包里的類的方式差不多。OuterA.InnerA();newOuterA.InnerAinna=inna.m1();//先生成一個外部類對象,之后用這個外部類對象OuterAout=newOuterA();OuterA.InnerBinnb=out.new一個內(nèi)部類對象。newInnerB( "hello");innb.m2();}}classprivateStringname1="hello" ;privatestaticStringname2="haha"publicstaticclassInnerA{public voidm1(){OuterA{;//name2是靜態(tài)成員//System.out.println(namel);//System.out.println(不能訪問外部類的非靜態(tài)成員。name2);}}publicclassInnerB{ //InnerB(Stringname){成員內(nèi)部類InnerBpublic}publicvoidm2(){//既能訪問靜態(tài)成員也能訪問非靜態(tài)成員。System.out.println(System.out.println(namel);name2);2023.局部內(nèi)部類a、 在方法體里定義的類;b、 局部內(nèi)部類里不能定義靜態(tài)的屬性和方法;c、局部內(nèi)部類只能訪問外部類中用 final修飾的常量;d、 如何在方法體外得到這個類的對象呢,通過方法的返回值就可以,返回值類型為Object。但是外部得到的這個對象是沒什么意義的, 因為只能訪問Object里的方法,此類自己的方法是訪問不到的。 解決方法:在外部定義一個接口, 然后此局部內(nèi)部類來實現(xiàn)接口,并實現(xiàn)接口中的方法,然后外部拿到對象后轉(zhuǎn)化成此接口類型就行了。再調(diào)用接口中的方法時,實際上是調(diào)用的局部內(nèi)部類中實現(xiàn)接口的方法。匿名內(nèi)部類a、 沒有名字的局部內(nèi)部類;b、 匿名內(nèi)部類沒有構(gòu)造函數(shù)(因為沒有名字) ,也不能被繼承;c、 匿名內(nèi)部類可以訪問外部類的成員:外部類名 .this?成員;d、 匿名內(nèi)部類如果聲明在方法中的話也具有局部內(nèi)部類的特點,只能調(diào)用 final的局部變量;e、 匿名內(nèi)部類中不能聲明靜態(tài)的成員;f、 匿名內(nèi)部類的聲明:聲明類型變量=new[類名extends/implements]聲明類型(){類的方法聲明...}[]中的是省略的部分;g、 匿名內(nèi)部類的聲明和對象的生成是合二為一,不可分割的;h、 得到的對象不知道是哪個類的對象, 只知道是實現(xiàn)了某接口或者繼承了某類的類的對象。publicclassInnerClassTest{publicstaticvoidmain(String[]args){OuterBout=newOuterB();//實例化一個Mylnter對象,在調(diào)用其中的方法,這時, 實際上調(diào)用的是實現(xiàn)它的內(nèi)部類的方法。MyInterobj=out.m1();obj.innerm();OuterCoutc=newOuterC();outc.m2(newMyInter(){publicvoidinnerm(){Mylntermyc= newMylnter(){publicvoidinnerm(){}};newMylnter(){publicvoid innerm(){}}.innerm();}}classOuterB{publicMyInterm1(){ // 返回一個Mylnter接口對象inta=10;finalintb=20;//實現(xiàn)Mylnter接口,并實現(xiàn)其中的方法。classInnerCimplementsMylnter{publicvoidinnerm(){System.out.println( "InnerC.innerm()" );//System.out.println("a="+a);System.out.println( "b="+b); //只能訪問外部類的常量。}}//返回一個內(nèi)部類的對象。returnnewInnerC();}}//定義一個Mylnter接口,讓局部內(nèi)部類去實現(xiàn)接口中的方法interface Mylnter{publicvoidinnerm();}classOuterC{//1、定義一個匿名內(nèi)部類,實現(xiàn)Mylnter接口,而且給出方法的具體實現(xiàn)。 2、生成該實現(xiàn)類的對象。(new)publicMylnterm1(){returnnewMylnter(){publicvoidinnerm(){

publicvoidm2(Mylntermyi){}}203 內(nèi)部類的應(yīng)用a、 如果一個類需要在多個類中使用,則考慮使用普通公開類;b、 如果一個類需要在一個類中多個方法里使用,考慮使用成員內(nèi)部類;c、 如果一個類需要在某個方法里多次使用,考慮使用局部內(nèi)部類;d、 如果一個類需要在某處使用一次,考慮使用匿名內(nèi)部類。集合框架(CollectionFramework)a、 數(shù)組的缺點:不能自動擴容,在剛創(chuàng)建數(shù)組時數(shù)組的空間不好確定;b、集合是一種數(shù)據(jù)結(jié)構(gòu),為了實現(xiàn)快速處理和高效的內(nèi)存利用率, 集合實現(xiàn)經(jīng)過精心構(gòu)造,集合通過其方便的功能鼓勵軟件的復(fù)用;c、 集合用來存儲數(shù)據(jù)一般能自動擴容,而且方便遍歷。Iterator接口和Iterable接口a、 Iterator:對collection進行迭代的迭代器(對集合對象循環(huán)訪問的工具);b、 Iterable:可迭代的,該接口是所有Collection集合的超級接口;c、 Iterable接口和Itertor接口沒有繼承與被繼承的關(guān)系;d、 Iterable接口中只有一個方法:publicIteratoriterator(){},第一個Iterator是返回值類型,第二個iterator是方法名,所以此方法返回一個Iterator對象,這是Iterable接口和Itertor接口唯一聯(lián)系;e、 因為所有的集合都實現(xiàn)了Collection接口,而Collection接口又實現(xiàn)了Iterable接口,Iterable中只有唯一的一個方法iterator,所以所有的集合對象都可以調(diào)用iterator方法,而調(diào)用iterator方法會返回一個Iterator對象,這樣就可以調(diào)用Iterator中的方法了。Connection接口和Connections類java.util.Collectiona、Connection接口是集合層次結(jié)構(gòu)中的根接口, Set和List都是其派生出來的子接口,它定義了在集合中添加、清除、遍歷元素的操作;b、 注意:add方法只能添加引用類型,而不能添加基本數(shù)據(jù)類型(可以使用包裝類)因為基本數(shù)據(jù)類型是存放在棧中的;c、remove方法移出對象時,會去調(diào)用對象的 equals方法,判斷對象是否相同;d、所有通用的Collection實現(xiàn)類應(yīng)該提供兩個"標準”構(gòu)造方法:一個是void(無參數(shù))構(gòu)造方法,用于創(chuàng)建空collection;另一個是帶有Collection類型單參數(shù)的構(gòu)造方法,用于創(chuàng)建一個具有與其參數(shù)相同元素新的collection;java.util.Collectionsa、 Connections類提供了集合的靜態(tài)方法,其中很多方法實現(xiàn)了用于查找和排序等功能的多態(tài)算法;b、 還提供了很多synchronized方法,可以直接調(diào)用這些方法,將線程不安全的Collection包裝成線程安全的Collection,這種方法很方便靈活;c、 Collections中有個Sort方法用于給List排序,Collections.Sort()分為兩部分,一部分為排序規(guī)則,一部分為排序算法;規(guī)則用來判斷對象,算法是考慮如何排序;d、 對于自定義對象,Sort不知道規(guī)則,所以無法比較,這種情況下一定要定義排序規(guī)則,方式有兩種(見排序的兩種辦法);e、 reverse方法,自動反向排序。List(列表)接口有序存放、允許重復(fù)ArrayLista、底層是數(shù)組實現(xiàn)的,實現(xiàn)了數(shù)組的變長,初始的數(shù)組容量默認是 10;b、數(shù)組實現(xiàn),遍歷快,增加刪除效率低;c、 ArrayList支持可隨需要而增長的動態(tài)數(shù)組:標準數(shù)組是定長的,在數(shù)組創(chuàng)建之后,它們不能被加長或縮短,這也就意味著你必須事先知道數(shù)組可以容納多少元素。但是,你直到運行時才能知道需要多大的數(shù)組。為了解決這個問題,類集框架定義了ArrayList。本質(zhì)上,ArrayList是對象引用的一個變長數(shù)組。也就是說,ArrayList能夠動態(tài)地增加或減小其大小。數(shù)組列表以一個原始大小被創(chuàng)建。當超過了它的大小,類集自動增大,當對象被刪除后,數(shù)組就可以縮?。籨、 盡管當對象被存儲在ArrayList對象中時,其容量會自動增加,仍可以通過調(diào)用ensureCapacity()方法來人工地增加ArrayList的容量。在開始時,通過一次性地增加它的容量,就能避免后面的再分配,因為再分配是很花時間的;e、 相反地,如果想要減小在ArrayList對象之下的數(shù)組的大小,以便它有正好容納當前項的大小,可以調(diào)用trimToSize()方法;f、 有時想要獲得一個實際的數(shù)組,這個數(shù)組包含了列表的內(nèi)容,可以通過調(diào)用方法toArray()來實現(xiàn)它,下面是幾個為什么可能想將類集轉(zhuǎn)換成為數(shù)組的原因:對于特定的操作,可以獲得更快的處理時間;為了給方法傳遞數(shù)組,而方法不必重載去接收類集;為了將新的基于類集的程序與不認識類集的老程序集成。LinkedLista、 實現(xiàn)了隊列(Deque)的接口,底層是鏈表實現(xiàn)的,先進先出;b、 鏈表實現(xiàn),遍歷較慢,增加刪除效率高;c、 此類實現(xiàn)Deque接口,為add、poll提供先進先出隊列操作,以及其他堆棧和雙端隊列操作;d、 所有操作都是按照雙重鏈接列表的需要執(zhí)行的,在列表中編索引的操作將從開頭或結(jié)尾遍歷列表(從靠近指定索引的一端)。Vector數(shù)組實現(xiàn)(和ArrayList一樣),同步的,線程安全,重量級的。(犧牲了效率,提高數(shù)據(jù)的安全性);而ArrayList是線程不安全的。Vector類現(xiàn)在已經(jīng)很少用了,因為現(xiàn)在的JDK提供了一個Collections類,該類中提供了很多synchronized的方法,可以將一個線程不安全的Collection包裝成一個線程安全的Collection。這比使用Vector要更方便更靈活。Set(集合)接口無序存放,不可重復(fù)。只有一個add方法,因為它是無序的,而List中有兩個add方法。其他的一些和下標有關(guān)的方法,在Set里面都沒有。常用的方法:clear、contains、isEmpty、remove、size、toArray。HashSet數(shù)組和鏈表實現(xiàn)的。 不排序的,不能重復(fù)的(hashCode相同,則覆蓋)。HashSet擴展AbstractSet并且實現(xiàn)Set接口。它創(chuàng)建一個類集, 該類集使用散列表進行存儲。正像大多數(shù)讀者很可能知道的那樣,散列表通過使用稱之為散列法的機制來存儲信息。在散列(hashing)中,一個關(guān)鍵字的信息內(nèi)容被用來確定唯一的一個值,稱為 散列碼(hashcode)。而散列碼被用來當做與關(guān)鍵字相連的數(shù)據(jù)的存儲下標。關(guān)鍵字到其散列碼的轉(zhuǎn)換是自動執(zhí)行的——你看不到散列碼本身。你的程序代碼也不能直接索引散列表。下面的構(gòu)造函數(shù)定義為:HashSet()HashSet(Collectionc)HashSet(intcapacity)HashSet(intcapacity,floatfillRatio)第一種形式構(gòu)造一個默認的散列集合。第二種形式用c中的元素初始化散列集合。第三種形式用capacity初始化散列集合的容量。第四種形式用它的參數(shù)初始化散列集合的容量和填充比(也稱為加載容量)。填充比必須介于0.0與1.0之間,它決定在散列集合向上調(diào)整大小之前,有多少能被充滿。具體的說,就是當元素的個數(shù)大于散列集合容量乘以它的填充比時, 散列集合自動擴容(從新做一次散列運算,得到新空間的新位置,而不是把原來位置的對象直接照搬過來) 。對于沒有獲得填充比的構(gòu)造函數(shù),默認使用 0.75。HashSet沒有定義任何超過它的超類和接口提供的其他方法。重要的是,注意散列集合并沒有確保其元素的順序,因為散列法的處理通常不讓自己參與創(chuàng)建排序集合。如果需要排序存儲,另一種類集 一一TreeSet將是一個更好的選擇。注:HashMap底層也是用數(shù)組,HashSet底層實際上也是HashMap,HashSet類中有HashMap屬性。HashSet實際上為(key.nuII)類型的HashMap。有key值而沒有value值。即:HashMap有鍵-值兩部分組成,而HashSet就是HashMap中的鍵的那一部分。所以HashMap和HashSet添加元素的規(guī)則是一樣的。注意:HashMap中的put方法(相當于HashSet中的add方法):如果本來有一條記錄:("zhangsan",20);再用put方法添加一條記錄:put("zhangsan",28);那么會將zhangsan鍵與28值相關(guān)聯(lián),覆蓋("zhangsan",20),返回20。而這樣的情況在HashSet中就表現(xiàn)為把元素舍棄掉了。底層用的是哈希散列表(長度 16的數(shù)組)來存儲對象,存放對象之前先做一個哈希散列運算(當要把對象放到到底層存儲方式為哈希散列的集合中的時候,系統(tǒng)會自動調(diào)用hashcode方法):1、 首先得到對象的哈希碼,就是用對象在內(nèi)存中的的首地址調(diào)用hashCode()方法,不同對象的首地址是不同的。publicinthashCode();返回一個int值,也就是哈希碼。還有Object類里toString方法默認返回的是:類名+@+地址,這里的地址也是用對象哈希碼的16進制表示的。如果我們覆蓋了hashcode方法,那么toString方法的返回值也將會跟這hashcode方法一起改變。API描述:publicStringtoString()返回該對象的字符串表示。通常, toString方法會返回一個"以文本方式表示”此對象的字符串。結(jié)果應(yīng)是一個簡明但易于讀懂的信息表達式。建議所有子類都重寫此方法。Object類的toString方法返回一個字符串,該字符串由類名(對象是該類的一個實例)、at標記符“@”和此對象哈希碼的無符號十六進制表示組成。換句話說,該方法返回一個字符串,它的值等于:getClass().getName()+@+Integer.toHexString(hashCode())hashCode()方法返回值的16進制形式,hashCode()方法返回的是對象的地址,是整型的。2、用hashCode()方法返回的哈希碼對 HashSet底層數(shù)組的長度求余,得到一個 0-15之間的值(默認16個長度),然后這個值就是存在HashSet數(shù)組中的下標,如果該下標位置上已經(jīng)有元素了,如果不沖突,就把這個對象放到該位置, 如果沖突的話,就對這兩個對象作比較,如果不相等,就把這個對象也放到這個位置,對于是怎么放的, 有可能每個數(shù)組元素都是一個鏈表,那么是此下標的元素如果equals比較的結(jié)果不相等,就會都放到這個鏈表中。如果他們比較是相等的,那么這個要被插入的對象就被拋棄掉了,沒有插入成功。HashSet比較兩個對象是否相等用的是 equals()方法。所以,只有同時覆蓋了對象的equals方法和hashCode方法,讓此方法按自己的算法運算的話才能算是相同的對象,覆蓋 hashCode方法的原則:原則1:讓equals相等的對象返回相同的hashCode,這樣用相同的哈希碼得到的下標將會相同,使相同對象得到的下標沖突,這樣就能過濾掉相等的元素。原則2:盡量保證(因為就算不同的對象,計算之后得到的下標也有可能相同) equals不相同的對象返回不同的hashCode(為了添加不同的元素)。原則3:盡量的讓對象的哈希碼隨即散列。(不要發(fā)生局部聚集,使哈希碼的取值范圍盡量散列開來)TreeSetTreeSet實現(xiàn)了Set接口和SortedSet接口。使用元素的自然順序?qū)υ剡M行排序,或者根據(jù)創(chuàng)建set時提供的Comparator進行排序,具體取決于使用的構(gòu)造方法。 (這里的自然順序,是指該對象實現(xiàn)了 Comparable接口后定義的compareTo方

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論