ThinkInJava筆記

這篇是大一的時候看ThinkInJava的時候隨後記錄的筆記,感覺還是那麼熟悉!

 


局部變量存放在內存的棧裏面,
內存分爲四塊:code segment 存放代碼;data segment 存放靜態變量   和字符串常量;stack 存放局部變量;heap 存放new出來的東西;


面向對象: 合適的方法應該出現在合適的類裏!
 1.遇到問題時,先抽象出來各個對象,以及各對象之間的關係!
 2.對於一個類,是有靜態屬性和動態屬性的!靜態屬性即爲成員變量,動態屬性即爲方法!深刻理解!
 3.類(對象)之間的關係之關聯關係:往往是一個方法裏的參數是另一個類的對象!
 4.繼承關係:XX是一種XX;
 5.聚合關係:XX是XX的一部分!
  聚合又分爲聚集和組合,聚集:關係不是很緊密;組合:關係非常緊密!
 7.實現關係:子類通過實現接口來實現自己的動作!
 6.面向對象考慮問題過程:首先,在這個問題中有多少個類多少對象;然後,考慮這些類這些對象應該有哪些屬性哪些方法:最後,考慮類與類之間有什麼關係!
 8.必須先定義類再定義對象!
 9.對象是JAVA語言的核心!可以看做是靜態屬性(成員變量)和動態屬性(方法)的封裝體;
 10.所謂靜態屬性,就是類中各個對象都應該具備但是又應該以此作爲區別各個對象的標準的屬性!深刻理解!
 11.JAVA裏面,除了基本類型以外,所有類型都是引用類型!
  基本類型只佔一塊內存,引用類型佔兩塊內存,棧和堆,棧中存放引用的地址,地址指向堆,堆中存放真正的new出來的東西!堆是動態分配內存的,類是靜態概念,位於代碼區!類的每個成員變量在不同的對象中都有不同的值(除了靜態變量)而方法只有一個,執行的時候才佔用內存!

 

 12.對象的創建與引用!
   對象(引用)有屬於自己的成員變量。對象共享該類的方法!
 13.stack是棧,用來存放引用!heap是堆,用來存放new出來的東西!可以理解爲對象的實體!該實體含有類的屬性,包括方法和成員變量!
 14.構建一個新對象的時候用構造方法!使用new+構造方法 創建一個新的對象!
 15.方法中的變量也存放在棧中,當方法調用完畢時,編譯器自動釋放棧空間!當調用方法時,傳遞進來的參數先在棧中存放,再由棧中的引用把值傳給堆並最終保存起來!任何局部變量都會存放在棧裏面!
 16.當構造方法沒有人工指定時,編譯器自動生成一個空的構造方法!
 17.分析程序時,從main方法的第一句來開始!
 18.原來,基礎變量只佔一塊內存,存放在棧裏!不是堆裏!
 19.垃圾回收機的原理:檢測一個對象,當沒有任何一個引用指向這個對象時,垃圾回收機就釋放這塊內存!
 20.不同的對象調用方法時,方法的作用域是不同的!因爲各個對象在堆中的屬性地址是不一樣的!所以方法以地址爲導向!
 21.方法的返回值也是暫時存儲在棧空間裏,當方法調用完畢時,有垃圾回收機釋放!

 22.方法重載,當方法名相同但是返回類型不一致時,會發生方法重名,這現象在編譯時就會報錯!
 23.是否構成重載關鍵看編譯器在調用這兩個方法時是否能夠根據參數列表來區分調用哪個方法!
 24.切記,構造方法也可以重載!
 25.同一個類的對象共享該類的方法!非靜態方法針對每個變量進行調用!
 26.方法只是一段代碼,所以應該保存在code segment中!當對象調用時,系統才爲該方法及其參數分配各個內存中的存儲空間,堆,棧都有可能!
 27.打印語句中如果包含方法返回值時,在打印語句輸出完畢以後方法返回值在棧中的存儲空間被釋放!
 28.字符串常量存儲在data segment區域!
 29.當涉及一個方法的創建時,考慮三個問題:方法的名字,方法的參數,方法的返回值!
 30.this 關鍵字,出現在類的方法定義中! this表示調用當前方法的對象的引用!注意,是引用!
 31.用this 來處理方法中成員變量和參數重名的現象!


 32.關於初始化:
     1.假設有個名爲dog的類。
    2.當首次創建類型爲dog的對象時(構造器可以看做是靜態方法),或者dog類的靜態方法/靜態字段首次被訪問時,java解釋器以定位dog。class文件。
     3.然後載入Dog.class文件(這裏將創建一個Class對象,貌似與getClass方法有關!),有關靜態初始化的所有動作都會執行,因此,靜態初始化只在Class對象首次加載的時候進行一次。
   4.當用new Dog()創建對象的時候,首先將在堆上位爲Dog對象分配足夠的存儲空間,
   5.這塊存儲空間會被清零,這就自動地將dog對象中的所有基本類型數據都設置成了缺省值,(對數字來說就是0,對布爾和字符也相同)對於引用則被設置成null。
   6.執行所有出現於字段定義處的初始化動作。
   7.執行構造器,正如將在第六章所看到的,這可能這可能會涉及到很多動作,尤其涉及到繼承的時候。
 33.對於static 變量,對對象來說只有一份,每個對象共享。
存放在data segment區域中!
  34.可以把static變量放在構造方法裏用作計數器!
 35.成員變量伴隨着對象的產生才產生於內存的堆中!
 36.main方法是靜態方法,對於非靜態的成員變量,必須藉助對象的調用才能在main方法裏訪問!這就是常說的“不能再靜態方法裏訪問非靜態變量!”同樣也不能在main方法裏直接訪問非靜態方法,對於非靜態方法和變量,必須藉助對象的引用才能訪問出來!
 37.靜態方法不再是針對某個對象的引用,所以不能訪問非靜態成員變量!
 38.注意,靜態方法和變量均可以被類名和對象調用!
 39.包名的命名,把公司的域名倒過來!

 


 40.繼承的內存關係:每一個子類對象中包含一個父類對象,(在堆中)
 41.子類繼承父類的時候,繼承父類的所有成員變量和方法,包括private變量,但是僅僅是擁有該類型變量的擁有權,卻無使用權!
 42.方法重寫:在子類中可以根據需要對從基類中繼承來的方法進行重寫;重寫方法必須和原方法有相同的方法名,返回類型,參數列表;重寫方法不能使用比被重寫方法更嚴格的訪問控制!
 43.方法的重寫是一種方法的拓展!
 44.注意重寫方法時,儘量去複製父類中的方法聲明,因爲一旦重寫時寫成了錯的方法,調用時只會調用父類中的方法,不會編譯錯誤!切記切記!
 45.在new對象的時候,this指向對象本身,super指向這個對象所包含的父類對象的引用!
 46.繼承中的構造方法:子類的構造方法的過程中必須調用其基類的構造方法。
 47.子類可以在自己的構造方法中使用super(argument list)調用基類的構造方法:使用this+參數列表 調用本類的另外的構造方法。
 48.如果調用super,必須寫子類構造方法的第一行。
 49.如果子類的構造方法中沒有顯示地調用基類構造方法,則系統默認調用基類無參數的構造方法。
 50.如果子類構造方法中既沒有顯式地調用基類構造方法,則編譯器自動加載父類的無參構造函數,如果父類沒有構造函數,則編譯器自動生成一個,從而保證編譯的通過,若父類有一個有參的構造方法,則編譯器不再提供無參構造函數,此時編譯出錯!
 

 

 51.如果在類的聲明中未使用extends關鍵字指明基類,則默認基類爲object類。
 52.toString方法是object類中的!返回類型爲字符串,當進行String與其他類型數據的鏈接操作時,將自動調用toString方法。可以根據需要在用戶自定義類型中重寫toString方法!
 53.Object 類的 toString 方法返回一個字符串,該字符串由類名(對象是該類的一個實例)、at 標記符“@”和此對象哈希碼的無符號十六進制表示組成。換句話說,該方法返回一個字符串,它的值等於:

getClass().getName() + '@' + Integer.toHexString(hashCode())
  54.toString方法在想直接輸出對象信息時調用,默認的實現形式是輸出類名+@+對象的哈希碼。所以要想輸出有價值的能讀懂的信息,必須在子類中重寫此方法!

 55.Object類之equals方法,該方法是繼承自object類,所以實現時需要重寫!通常有必要重寫hascCode方法!以維護哈希規範,該協議聲明相等對象必須具有相等的哈希碼!
 56.equals方法在object類下的實現方法就是比較兩個引用是否指向同一個對象,即A==B時,即當把B的引用賦值給A時才返回true.
 57.對象轉型:1 一個基類的引用類型變量可以“指向”子類對象。2 一個基類的引用不可以訪問其子類對象新增加的成員。3 可以使用instanceof 類名來判斷該引用型變量所指向的對象是否屬於該類或該類的子類。4 子類的對象可以當做基類的對象來使用稱作向上轉型(upcasting) 反之稱爲向下轉型(downcasting)
 58.注意,instanceof關鍵字是判斷當前引用是否指向該類或該類的子類,只要滿足其中一個則返回true
 59.對象轉型的第二個應用:把父類對象作爲參數傳遞進方法,同樣可以把該父類的子類對象也傳進去,然後用instanceof來檢索進來的這個對象具體是指向那個類的。然後把該對象強制轉換成該類對象,然後再用if語句來具體執行屬於該具體類的相關方法!
 60.在父類引用指向子類對象的時候,如果該父類引用調用了一個方法,且這個方法在各個子類中都有重寫,則具體調用哪個類的方法則由該父類對象最終實際指向的對象的類決定,也稱爲:動態綁定!多態,遲綁定!
 61.利用這種動態綁定機制使程序的可拓展性發展到最好!
 62.所謂動態綁定是指在“執行期間”非編譯期間,判斷所引用對象的實際類型,根據其實際類型調用相應的方法!
 63多態存在的3個條件:要有繼承,要有重寫,要有父類引用指向子類對象!
 64.當一個類包含抽象方法時,這個類必須被聲明爲抽象類!
 65.當繼承該類時,必須要實現該方法!
 66.抽象類必須被繼承,抽象方法必須被重寫!
 67.注意,抽象方法聲明時要加分號!
 68.final的變量不能被改變。final的方法不能被重寫,final的類不能被繼承!final起到一個鎖定的作用!


 69.接口interface是抽象方法和常量值的定義的集合!從本質上講,接口是一種特殊的抽象類,這種抽象類只包含常量和方法的定義,而沒有變量和方法的實現!
 70.接口支持多繼承,接口中的屬性默認爲public static final 的,也只能是public static final的!接口可以繼承,添加新的屬性和抽象方法!而且方法只能是public的!
 71.多個無關的類可以實現同一個接口!一個類可以試想多個無關的接口!與繼承關係類似,接口與實現之間存在多態性!
 72.訪問權限的控制常被稱爲隱藏具體實現,把數據和方法包裝進類中,以及具體實現的隱藏,常共同被稱作是“封裝”,其結果是一個同時帶有特徵和行爲的數據類型!
 73.類的權限只有包權限和public,要想該類的對象不能在其他類中被創建,則只需把該類的構造定義爲private,這種情況內部類除外!
 74.當想要爲把構造方法設置爲private的類創建對象時有如下方法:1.創建一個static方法 返回類型爲該類的對象,然後實際返回new 類名+構造;2 用private static 創建一個對象,然後創建一個static方法 返回該對象的一個引用!需要對象時就直接用該方法調用引用來實現!
 75.奇妙問題,當一個類實現了兩個接口,這兩個接口中有同樣方法名的兩個方法,則在類中具體實現這兩個方法時是不會出錯的!
Eclipse除外!貌似Eclipse不允許同名的方法出現!
 76.private 和final的類不能被繼承!但是隻有內部類能被private修飾!


 77.異常處理,觀察錯誤的名字和行號最重要!程序是調出來的

 78.當捕獲異常後,通常的處理方式是e.printStackTrace();這是打印出錯誤的堆棧信息,堆棧信息對調試程序很有幫助!

 79.java的程序執行過程中如出現異常事件,可以生成一個異常類對象,該異常類對象封裝了異常事件的信息並將被提交給java運行時系統,這個過程成爲拋出(throw)。
 80.當java運行時系統接收到異常對象時,會尋找能處理這一異常的代碼,並把該對象交給其處理,這一過程稱爲捕獲(catch)。
 81.對於異常,分爲error和exception,error不可處理,屬於系統錯誤,exception可以被處理,又分爲runtimeexception與必須捕獲的異常,對於runtimeexception可以不捕獲,但是另外一種必須捕獲!
 82.注意一個try可以拋出多個異常,對應的,多個catch與一個try配套使用!

 83.try語句,指定了一段代碼,該代碼就是一次捕獲並處理例外的範圍,在執行的過程中,該代碼可能會產生並拋出一種或幾種異常的對象,try後面的catch負責分別處理這些異常,如果沒有例外產生,所以得catch代碼都被跳過!
 84.catch就是對異常進行處理的代碼,在catch中聲明的對象,封裝了異常事件發生的信息,在catch語句塊中可以使用這些信息!如getMessage(),用來得到有關異常事件的信息,printStaceTrace()方法用來跟蹤異常事件發生時執行堆棧的內容!
 85.finall語句,爲異常處理提供一個統一的出口,使得在控制流程轉到程序的其他部分以前,能夠對程序的狀態作統一的管理。
 86.無論try指定的程序塊中是否有拋出例外,finally所指定的代碼都要被執行。
 87.通常在finally語句中可以進行資源的清除工作,如:關閉打開的文件,刪除臨時的文件!
 88.捕獲異常以後一定要作出處理,比如getMessage,printStackTrace等!
 89.當捕獲的異常不想處理時,可以在main方法裏拋出去,交給java運行時系統,但是這是很不好的編程習慣,杜絕!
文明的處理方式就是寫try---catch方法!
 90.throws關鍵字的用途就是拋出異常,以等待一個try---catch組合來捕獲並處理!由catch內的資料來處理。
 91.捕獲異常的時候先捕獲小的,再捕獲大的!
 92.自定義異常,通過繼承java.lang.Exception類聲明自己的異常類;在方法的適當的位置生成自定義異常的實例,並用throw語句拋出;在方法的聲明部分用throws語句聲明該方法可能拋出的異常!
 93.注意throw在方法內部使用來拋出,throws在方法聲明時使用來拋出!
 94.繼承中的異常問題,重寫方法需要拋出與原方法所拋出異常類型一致異常或不拋出異常。

 

 95.數組:c\c++中的數組允許分配在棧上,而java是引用類型!
 96.數組裏裝的都是引用!java裏聲明數組時不能指定數組的長度:int a [] 是錯誤的!
 97.當僅僅聲明數組時,內存中只是在棧上創建一個數組裏面放着null的初始引用!當用new關鍵字來初始化數組時,內存中堆上劃分出一個與數組長度一致的區域!裏面的數據已經被初始化!初始化規則與成員變量的規則一致!然後棧中的引用根據數組下標分別指向這些在堆中的具體數組值!
 98.數組初始化分爲靜態初始化和動態初始化。動態初始化就是數組定義與爲數組分配空間和賦值操作分開進行!
 99.當程序涉及到輸入輸出時,判斷一下,以防出現錯誤,這樣的程序設計友好!當然要先把程序的主體流程涉及好!
 100.當必須親自處理垃圾時,就要多加小心了,因爲一旦涉及垃圾回收,能夠信賴的事就不多了!垃圾回收器可能永遠不會被調用,即使被調用,它可能以任何它想要的順序回收對象,最好的方法,是除了內存外,不要依賴垃圾回收器做任何事,如果需要進行清理,最好是編寫好你自己的清理方法,但不要依賴finalized().
 101.對象型的成員變量,可以被該類的對象調用,在由這個被調用類調用屬於它自己的方法!很另類!
 102.(is-a)用來表示繼承關係,(has-a)用來表示組合關係!
 103.如果將項目視作一種有機的,進化着的生命體去培養,而不是像打算蓋摩天大樓一樣快速見效,就會獲得更多的成功和更迅速的回饋!
 104.final型數據並不是在編譯時就知道數值,若把它定義爲隨機數就不可知了,final static型量在編譯器首次裝在它時就已確定,不可再變。
 105.帶有初始值的final static基本類型全用大寫字母命名,而且字與字間用下劃線隔開。
 106.final對基本數據類型僅僅是使值不變。final對引用的作用爲一旦引用被初始化指向一個對象,就無法再改變這個引用指向的對象,但是可以改變實際對象的值!
 107.空白final java允許使用final定義空成員變量,和引用,但該類變量必須在構造中北初始化。
 108.參數列表,在參數列表中把類型設爲final可以鎖定該參數的引用不變。即不能更改,即只能被一個對象調用一個!這是一種安全策略。
 109.final方法,把方法定義爲final型目的:1.鎖定方法,以防任何繼承類修改它的定義,處於設計的考慮,來確保在繼承中使方法行爲保持不變且不會被覆蓋。2.效率:統一編譯器對該方法的所有調用都轉爲內嵌調用!
 110.方法的返回值可以是數組!因爲數組是引用類型,對象類型也是引用類型!
 111.理解數組中的引用:數組名是一個變量,存在棧裏,然後該引用指向堆中的空間,該空間被分爲好多小格,長度爲數組長度,然後該空間中的每個小格又指向堆中具體的對象!如是而已!
 112.
 110.private 與final:類內所有的private方法都隱式地被指定爲final,由於無法去用private方法,所以就無法覆蓋它!
 111.覆蓋只有在方法是基類的接口的一部分時纔會實現,即必須能將一個對象向上轉型爲它的基本類型,並調用相同的方法,如果某方法爲private它就不是基本接口的一部分,它僅僅是一些隱藏於類中的程序代碼,只不過是具有相同名稱而已,但若在導出類中以相同名稱生成一個public,protected或包訪問權限的話,該方法就不會與基類方法形成覆蓋,僅是到處類的一個方法而已,由於private方法無法觸及而且能有效隱藏,所以除了把它看成是因爲它所歸屬的類的組織飢餓結構的原因而存在外,其他任何事物都不要考慮它。
 112.final類:final類不允許別人這樣做,換句話說出於某種考慮,該類不需要任何變動,出於安全考慮,你不希望它有子類,final類中所有方法都隱式地指定爲是final的,因爲無法覆蓋它們!
 113.面向對象思想中,問題域裏的名詞一般爲類,動詞爲方法,賓語爲參數列表!
 114.注意,搜索往往是建立在排序的基礎上!


 115.排序算法:選擇排序法!利用兩層for循環遍歷數組!注意,第一層I 次二層J=I+1;定義一個temp,當發現I>J時,先把I賦值給temp,再把J賦值給I,再把temp賦值給J如是而已!
 116.冒泡排序法:仍然是兩層for循環,注意,第一層中I定義爲數組的最後一個值,然後I--,第二層中J從0開始++,當發現j>j+1時,就把j賦值給temp,把j+1賦值給j,把temp賦值給j+1;如是而已!
 117.四維數組在3D的圖形轉換裏是有用的!
 118.java裏數組的聲明順序是從左到右的(從高維到低維)
 119.數組初始化分爲靜態和動態,靜態初始化多數組時不能指定[]內的數字!java自動根據大括號後的內容予以初始化!
 120.java裏面的多維數組是數組中的數組! 比如:int a [] [] = new int [2] [3];裏面的a.length 就是第一維的長度!
 121.String型數組裏存放的都是String的引用!初始都爲null,隨着new來在堆中創建對象!
 122.數組在內存中的區域往往都是連續的!所以當需要把數組中的數據拷貝出來時!直接用方法System.arraycopy就行!有四個參數,第一個是開始數組名,第二個是數組的開始位置,第三個是目標數組名,第四個是目標數組的開始位置,最後一個是複製開始數組的長度,類似方法在C裏叫memory copy。
 123.當完成數組的複製以後!兩個數組真正指向的是內存中的相同內容!因爲複製操作時造作的引用! 當對一個數組的內容進行更改之後,另一個數組也同步更改!
 124.當抽象方法在已經被覆蓋的方法中調用時,由於抽象方法無方法體,所以會調用導出類中的被覆蓋的方法。構造方法自動屬於static型!
 125.初始化順序:1.在其他任何事發生前將分配給對象的存儲空間初始化成二進制的0。
   2.先調用積累的構造器,若該構造器中有抽象方法,則調用該構造方法的被覆蓋方法,然後再調用導出類的構造方法。
  126.編寫構造器時有一條有效的準則,用盡可能簡單的方法使對象進入正常狀態,如果可以的話,避免調用其他方法,在構造器中唯一能夠完全調用的方法使基類中的final方法(也適用於private)它們自動屬於final型!
 127.在不知道類與類具體的結合方式時,首選組合!因爲繼承是一個嚴謹的體系!
 128.用繼承表達行爲間的差異,用字段表示狀態上的變化。即通過繼承得到不同的類,這樣就有了被覆蓋的不同的基類方法,即行爲,用類(字段)或代碼塊來操縱引用來改變狀態,如改變一個對象的引用!
 129.基類引用指向導出類對象就是一種向上轉型,這樣,基類可以接收發送給導出類的任何信息,因爲繼承使它們擁有完全相同的接口(成員變量和方法),我們只要向上轉型自然就會執行導出類的相關方法,這是多態的靈活之處。
 130.向上轉型會使對象丟失在導出類中拓展出來的方法,因此有向下轉型,向上轉型是安全的,但向下轉型不安全。在c++中我們必須執行一個操作來獲得安全的向下轉型,但java中,所有的轉型都會得到檢查,這種檢查叫做運行時檢查(RTTI)若向下轉型不正確,則返回一個ClassCastException。
 131.這裏的轉型成功是指導出類的引用被正確地指向導出類對象,而該對象初始是指向基類的。
 132.爲了在自己的程序中有效地運用多態乃至面向對象技術,必須拓展自己的編程視野,使其不僅包括個別類的成員和消息,而且還要包括類與類之間的共同特徵,及它們之間的關係,儘管這需要極大的努力,但是這樣做是非常值得的,因爲它可以帶來很多成效:更快的程序開發過程,更好的代碼組織,更好的拓展性!
 133.接口:接口用來建立類與類之間的協議!interface中的方法隱式地維public,所以具體實現時也只能是public,否則會導致該方法的訪問權限被降低,所以java不允許!
 134.equals方法使object提供的,在java.lang中已經被重寫,重寫內容爲比較兩個字符串的實際值!所以在String中調用equals方法時,不必再手動重寫!
 135.String s1 = "java";
  String s2 = "java";
  String s3 = "sun";
  
  System.out.println(s1 == s2);
   如上所示,輸出結果爲true,因爲s1 s2不是new出來的,只是字符串常量,存放在data segment區域中! 編譯器對該區域中的變量有個優化,當生成s2時,由於已經存放了 與s2一樣的值,所以編譯器就直接把s2 的引用指向s1,所以就比較出同樣的結果!
 136.String s1 = "java";
  String s2 = "java";
  String s3 = new String("sun");
  String s4 = new String("sun");
  
  System.out.println(s1 == s2);
  System.out.println(s3 == s4);
  System.out.println(s3.equals(s4));
  如上所示,輸出結果爲TRUE,false ,true。 因爲s3,s4都是new出來的,所以編譯器保存在heap中,分別分配內存!當比較引用時當然不一樣,由於equals方法在java.lang中被覆蓋,所以第三個結果爲true。
 136.s4.length()返回的是字符串的長度,單位爲字符,不是字節!
 137.
  String s7 = "sun java";
  String s8 = "          Sun          Java          ";
  System.out.println(s7.charAt(4));
  System.out.println(s7.equals(s8));
  System.out.println(s7.equalsIgnoreCase(s8));
  System.out.println(s7.replace('s', 'A'));
  System.out.println(s7.isEmpty());
  System.out.println(s7.indexOf("java"));
  
  System.out.println(s7.startsWith("sun"));
  System.out.println(s7.endsWith("java"));
  System.out.println(s7.toUpperCase());
  System.out.println(s7.toLowerCase());
  System.out.println(s8.trim());
  String s9 = s7.substring(4,8);
  System.out.println(s9);
  注意substring方法是左開右閉的!
 138.String.valueOf(...)可以把基本類型轉換成字符串,也可以把對象轉換成字符串,這裏存在多態,因爲它調用的對象的toString方法,而又存在對象轉型!
 139.多態是面向對象的最核心部分!
 140.無論是將對象向上轉型爲普通類,抽象類,接口,都不會有問題,它們的行爲是相同的,注意,可以向上轉型爲接口,並調用接口中的方法,不過實際調用的應該是該接口方法的具體實現方法!
 141.使用接口的核心原因:爲了能夠向上轉型爲多個類型,然而使用接口的第二個原因卻是與使用抽象基類相同:防止客戶端程序員創建該類的對象,並確保這僅僅是建立的一個接口。
 142.既然接口帶來了抽象類的好處,並且還帶來了使用接口的好處,所以如果要創建不帶任何方法定義和成員變量的基類,那麼就應該選擇接口而不是抽象類,事實上,如果知道某事物應該成爲一個基類,那麼首選它成爲一個接口,只要強制你必須要有成員變量和方法定義時,才應該改而選擇抽象類或者在必要時使其成爲一個具體基類!
 143.重載的方法可以通過參數列表,返回值來區分,但重寫的方法必須完全一致!
 144.通過繼承可以很容易的在接口中添加新的方法聲明,還可以通過繼承在新接口中組合數個接口。
 145.注意:extends 繼承類時只能有一個, 但extends 繼承接口時,可以是多個,僅需用逗號把接口名間隔開!
 146.java.lang.StringBuffer 代表可變的字符序列!
 147.StringBuffer和String類相似,但StringBuffer可以對其字符串進行改變!
 148.StringBuffer類的常見構造方法:
   1.StringBuffer():創建一個不包含字符序列的“空”的StringBuffer對象。
  2.StringBuffer(String str):創建一個Stringbuffer對象,包含與String對象str相同的字符序列!
 149.注意:StringBuffer中的reverse,append方法可以用在機器人中!
 150.String不可變,Stringbuffer可變!區別在於內存中!比如:同樣是合併字符!在String中必須開闢另外一塊內存!來存放用於合併的幾個字符串的和然後再把引用返回出去! 但是同樣的工作在Stringbuffer中!只需直接在目標的內存中更改即可!這也就是可變與不可變的區別!注意!注意!
 151.基礎數據類型都是分配在棧上!若想把它們存儲在堆上就需要基礎類型的包裝類來包裝一下基礎類型!
 152.注意:包裝類中的System.out.println(Integer.toBinaryString(123)+" B"); 用途可以用於機器人的加密解密! 先把用戶輸入的密碼轉換成二進制,再用於其它迷惑!
 153.調試程序的時候打印一些消息對調試程序很有幫助!
 154.注意二維數組的初始化!動態初始化時可以:double[][] d ;這樣來聲明,初始化第一維長度時:d = new double[3][] 注意要加兩個中括號!初始化第二維長度時d[i] = new double[4];注意!

 155.Math類:java.lang.Math提供了一系列靜態方法用於科學計算;其方法的參數和返回值類型一般爲double,也就是說,一般調用math方法時需要類型轉換!
   1.abs 絕對值。
   2.acos,asin,atan,cos,sin,tan
   3.sqrt 平方根
   4.pow(double a,double b) a的b次冪
   5.log 自然對數
   6.exp e爲底的指數
   7.max(double a,double b)
   8.min(double a,double b)
   9.random()返回0.0到1.0的隨機數
   10.long round(double a)double型的數據a轉換爲long型(四捨五入)
   11.toDegress(double angrad)弧度-》角度
   12.toRadians(double angdeg)角度-》弧度
 156.計算機文件系統記載文件修改時間都是以毫秒爲單位的一個long型數值!該數值表示從上次文件被修改到現在經歷的毫秒數!
 157.反斜槓\在java裏是一個轉義字符,所以在java裏用\\來表示 一個\。而在linux下都是以正斜槓/來劃分文件目錄的,windows也支持這種寫法!所以/是windows和Linux下共同兼容的!
 158.注意:用File類尋找文件的目錄時,當該文件是位於一個包中,這時找出來的目錄是包上一層的目錄!
 159.常用接口來創建常量組:public interface Math { int JANUARY = 1;} 調用時只需Math.JANUARY即可,注意:不可變的常量名全部大寫,用_來間隔單詞。
 160.接口可以嵌套,接口內部的接口不能被定義爲private,但被繼承的接口允許。 實現一個private接口,只是一種方式,它可以強制接口中的方法定義不能添加任何類信息(不能向上轉型)。
 161.內部類:如果想在外部類的非靜態方法之外的任何位置創建某個內部類的對象,那麼必須像在main方法中那樣具體的指明這個對象的類型:OutClassName.InnerClassName
 162.可以把內部類向上轉型爲接口,來隱藏大量內部類中的具體實現。但private的InnerClass只能通過在它的包含類中,用一個能返回它的引用的方法,然後用該包含類的一個對象來調用這個方法的方式來把內部類的引用傳遞出來!
 163.作用域可以理解爲代碼塊,即{}之間的部分!
 164.內部類不僅可以放在類作用域中,也可以放在方法作用域或任意的代碼塊中。這樣做有兩個理由:1.你實現了某類型的接口,於是可以創建並返回對其的引用。
  2.你要解決一個複雜的問題,想要創建一個類來輔助你的解決方案, 但又不希望這個類是公共可用的。
 165.內部類貌似是用來隱藏具體實現的!
 166.內部類的幾種用途:1.一個定義在方法中的類;2.一個定義在方法的作用域中的類;3.一個實現了接口的匿名類;4.一個匿名類,它擴展了有非缺省類型的構造器的類;5.一個匿名類,它執行字段初始化;6.一個匿名類,它通過實例初始化來實現構造器。

 167.當內部類被創建在方法的作用域中時,只可以在該方法的作用域中創建它的對象。
 168.也許大括號後跟分號的情況1.abstract方法後;2.匿名內部類後。
 169.定義匿名內部類:public classic A {
                                     public B cont() {
                                              return new B () {
                                                  private interface id = 11;
                                              public int value () { return id  }   上面實際表示創建一個繼承自B的類的對象,通過new 表達式返回的引用被自動轉型爲B。
 170.如果定義一個匿名內部類,並且希望它使用一個在其外部定義的對象,那麼編譯器會要求其參數引用時final 的,如果忘記,將會得到一個編譯時的錯誤消息。
 171.如果想爲匿名內部類添加構造動作,可以利用基類的構造器(基類爲抽象類)(個人看法)
 172.實力初始化內部類貌似字段的初始化,沒感覺!內部類擁有其外部類所有元素的訪問權。
 173.內部類對外圍類的訪問權限如何做到:當某個外圍類對象創建某個內部類對象時,此內部類對象必須保存一個指向那個外圍類對象的引用,然後在你訪問外圍類成員時就是用那個隱藏的引用!
 174.內部類聲明爲static時不會生產指向外圍類的隱藏引用,這種內部類叫做嵌套類。
 175.嵌套類表示:1.要創建嵌套類的對象並不需要其外圍類的對象;2.不能從嵌套類中訪問非靜態的外圍類對象;3.普通內部類的字段與方法只能放在類的外部層次上,所以普通的內部類不能有static數據和static字段,也不能包含嵌套類,但嵌套類可以。
 176.在一個普通的非static內部類中,通過一個特殊的this引用,可以連接到其外圍類對象,嵌套類就沒有這個引用,因此它更像一個static方法! 
 177.正常情況下,不能在接口內部放置任何代碼,但嵌套類可以所謂接口的一部分,因爲類是static的,只是將嵌套類置於接口的命名空間內,並不違反接口機制。
 178.可以用嵌套類來放置測試代碼!從而不必寫出main方法!               


 179.在外圍類中創建內部類對象時必須先創建外圍類對象,然後用該對象調用相關方法來創建內部類對象,因爲創建內部類對象時會悄悄地連接到創建它的外圍類的對象,然而若是嵌套類就不需要對其外圍類的引用!
 180.繼承了內部類的類在創建構造器時,缺省的構造器不可用,因爲導出類中不再有內部類可以默認連接到的外圍類對象,因此,必須在構造器中傳遞內部類的外圍類引用,然後再域中用該引用調用外圍類的無參構造器。
 181.內部類可以被繼承,但必須有導出類明確地指出extends 外圍類名.內部類名
內部類卻不可以像方法一樣被繼承其外圍類的導出類“覆蓋”
 182.使用局部內部類而不使用匿名內部類的唯一理由:需要不止一個該內部類的對象。
 183.內部類最吸引人的原因:每個內部類都能獨立地繼承自一個(接口)的實現,所以無論外圍類是否已經繼承了某個接口的實現,對於內部類都沒有影響。
 184.內部類使得多重繼承的解決方案變得完整:接口解決了部分問題,而內部類有效地實現了多重繼承,也就是說:內部類允許繼承多個非接口類型(實體類或抽象類)。
 185.重要理解:內部類可以通過繼承和操縱其他對象使類變得更健壯。符合客觀的哲學思想:當一類個體發展到一定程度,會在內部產生或形成一個團體,這個團體對類有無限制的權限,可以對類產生影響,或者說是影響類的行爲!比如:領導階層!
 186.如果解決面臨實現多個接口的問題,則使用內部類與單一類無太大差別。若問題面臨是實現多個抽象類或者是實體類,只有用內部類才能實現多重繼承。
 187.使用內部類獲得的特性:1.內部類可以有多個實例,每個實例都有自己的狀態信息,並且與其外圍類對象的信息相互獨立。
      2.在單個外圍類中,可以讓多個內部類以不同的方法實現同一個接口,或繼承同一個類。
      3.創建內部類並沒有令人迷惑的“is-a”關係,它就是一個獨立的實體。
 188.注意:內部類居然有權操縱外圍類的private成員!
 189.閉包:是一個可調用的對象,它記錄了一些信息,這些信息來自於創建它的作用域,也就是說內部類是一種閉包!通過內部類提供閉包的功能是完美的解決方案,它比指針更靈活,更安全。closure:閉包!callback:回調!

 190.內部類 = 閉包 = 創建它的作用域信息 + 指向該作用域信息的引用。這個引用向其他類提供了一種訪問該內部類的外圍類的各個成員(包括private)的途徑;若此內部類再實現了某個接口,則這個引用可以被其他實現該接口的類的對象使用,這是一種複雜但更靈活的類類關係,多態貫穿其中,博大精深!
 191.Framework(框架)是被設計用來解決某些特定問題額一個類或一組類,要運用某個應用程序框架,通常是集成一個或多個類,並覆蓋某些方法,在覆蓋後的方法中,編寫代碼‌定製應用程序框架,提供的通用解決方案,以解決特定問題(這是設計模式中的“模板方法”)
 192.內部類與控制框架:1.內部類允許用單一的類完整地實現控制框架,從而將實現的細節封裝起來,內部類用來表示解決問題所必須的各種不同的action()
                    2.內部類能夠很容易地訪問外圍類的成員,所以可以避免這種實現變得笨拙。
 193.當需要實現多個接口時,不妨添加一個總接口,然後由該接口繼承其他接口,再用目標類實現該接口,當然,還是必須要實現所有接口中的方法! 
 194.注意:在返回接口引用時,別忘了new後的構造方法:return new類名();
 195.在方法中創建匿名內部類時,若方法返回類型爲一個類的名字,則該類必須存在,表示該匿名內部類匿名繼承自此類!
 196.定義內部類時,注意類名後不要加括號,注意類的聲明格式與方法的格式,注意區分!
 197.在外圍類中調用內部類一般都是在外圍類中創建一個能返回該內部類引用的方法,然後通過外圍類對象調用該方法在調用內部類包含的一切動作!
 198.創建一個包含內部類的類,再在另外一個類中創建該內部類的實例:
  具體實現方式就是在另外一個類中,先創建它的外圍類的對象,然後用外圍類名.內部類名 標識符 = 外圍類對象名.內部類名();

如:package InnerandInterface;
class Inner3 {
 class Inner33 {
  public Inner33() {
   System.out.println("I am InnerClass33");
  }
 }
}
public class TestInnerClass8 {
 public static void main(String args[]) {
  Inner3 i3 = new Inner3();
  Inner3.Inner33 i33 = i3.new Inner33();
 }

}


 191.枚舉類型:只能取特定的值之一;使用enum關鍵字,是java.lang.Enum類!
 192.注意,枚舉類型是一種類型,並非成員變量!定義如下:public class TestEnum {
 public enum MyLove  {
  yuer,shang,yaner,momo
 }
 
 public static void main(String args[]) {
  MyLove ml =  MyLove.shang;
  switch(ml) {
  case yuer: System.out.print("you love yuer");break;
  case shang: System.out.print("you love shang");break;
  case yaner: System.out.print("you love yaner");break;
  case momo: System.out.print("you love momo");break;
  
  }
 }

}
   注意:聲明時不用 “=”,直接包含在大括號裏,定義引用時不用構造!所以枚舉類型的對象更像static型量!


 193.容器類:Collection接口定義了存儲一組對象的方法,其子接口Set和List分別定義了存儲方式。Set中的數據對象無順序不可重複,List中的數據對象有順序可以重複,注意這裏的重複指的是兩個對象equals!
 194.Map接口定義了存儲鍵值對的方法!
 195.注意,容器中存放的是對象,如果想存放基礎類型,必須用相應的包裝類將其包裝成對象,因爲基礎類型存放在棧中,棧中的數據隨時有可能被清空!
 196.注意這種寫法: Collection c = new ArrayList(); 父類引用指向子類對象,保證的將來代碼的拓展性!
 197.注意:調用remove方法時,比較的是對象的equals方法,如果對象是手動創建類的,那麼如果類中沒有重寫Object類的equals方法,則永遠不會移除此對象,因爲引用永遠不會一樣!如果是用基本數據類型包裝的基本類型!則會正常移除,因爲所有包裝類都已經重寫了equals方法!
 
 198.容器類對象在調用remove、contains 等方法時,需要比較對象是否相等,這會涉及到對象類型的equals方法和hashCode方法;對於自定義的類,需要重寫equals和hashCode 方法以實現自定義的對象相等規則。注意:相等的對象應該具有相等的hash codes。
 199.當對象用在Map接口中用作“鍵”,時比較方法會選擇hashCode。重寫equals方法必須重寫hashCode方法!
 

 200.所有標準異常類都有兩個構造器,一個無參,一個接受字符串參數,以便能把相關信息放入構造器!
 201.fillInStackTrace用來用來更新異常發生的地點信息!調用時如:e.fillInStackTrace()
 202.fillInStackTrace返回的是對Throwable的引用,爲了使所有異常都能捕獲,自定義異常都繼承自Throwable。
 203.異常的基本概念是用名稱代表發生的問題,並且異常的名稱應該可以望文知義。
 204.如果把try塊放在循環裏,就建立了一個“程序繼續前必須要達到的”條件,還可以加入一個static類型的計數器,或別的裝置,使循環再放棄以前能嘗試一定的次數。
 205.在構造方法裏拋出異常:很有意思!
 206.進行向下轉型前,如果沒有其他信息可以告訴你這個對象是什麼類型,那麼使用instanceof是必要的, 通常用提問的方式:if(x instanceof Dog)……
 207.Iterator是用於各個集合的迭代器,也就是用來遍歷各種容器的成員的一個接口,包含於java.util包中,使用的時候:Tierator i = c.iterator()這樣這個I 就是一個接口對象,用於遍歷各個容器,注意,他有三個方法:hasNext(), next(),remove() 返回類型依次是boolean,Object,void,其中remove方法是在容器中刪除元素的唯一安全的方法!因爲當用iterator接管容器進行操作時,iterator鎖定當前對象,不允許外部操作,比如collection的remove方法等!注意:鎖定!
 
 208.把iterator看成一種遊標,其中remove方法是刪除遊標左邊的對象!
 209.JDK1.5中提供了增強的for循環,語法:int[] dest = {4,3,6,2,8,5};
  
  for(int h : dest) {
   System.out.print(h+" ");
  }
 但是這種for循環只是用於簡單的遍歷數組元素,有兩個缺陷:1.數值中:不能方便的訪問下標值。
  2.集合中:與使用Iterator相比,不能方便的刪除集合中的內容,在增強的for循環內部也是調用Iterator。
總結:除了遍歷並讀出其中的內容外,不建議使用增強for。
 210.Set接口時Collection的子接口,Set接口並沒有提供新的子方法,Set接口的容器類中的元素是沒有順序的,但是不可用重複!Set容器可以與數學中“集合”的概念相對應!J2SDK API中,所提供的Ste容器類有HashSet,TreeSet等!
 211.注意,在Set中可以添加相同的對象,因爲其內存地址是不同的,但是不能打印出相同的元素!
 212.    Set s1 = new HashSet();
  Set s2 = new HashSet();
  s1.add("s"); s1.add("h"); s1.add("a"); s1.add("h");
  s2.add("g"); s2.add("s"); s2.add("a"); s2.add("n");
  
  Set sn = new HashSet(s1);
  sn.retainAll(s2);
  
  Set su = new HashSet(s2);
  su.addAll(s2);
  注意retainAll方法,用於求兩集合的交集,addAll用於合併兩集合!

 213.數據結構的選擇:Array讀快改慢;Linked改快讀慢;Hash兩者之間!
 214.map中添加對象時,可以直接添加基本類型,不必非得用包裝類將其包裝成對象再放進 map中,原來:m1.put("one",new Integer(3)); 現在:m1.put("one",1);即可!
 215.注意:在map中放進去跟拿出來的value都是Object對象!注意出來使用前的類型強制轉換!
 216.泛型使用來規範放入集合中的對象的,爲了使對象在取出來時仍然能保留自己的特殊類型,使用泛型!
 217.for循環中,如果要省略第三個條件,必須在第二個條件後加分號!
 218.容器這一章1136:一個圖,一個類:Collections,三個知識點:增強的for,generic,auto-boxing/unboxing; 六個接口:collection set map list iterator compareable。


 219.class有幾個方法,可以在運行時獲得類的相關信息,詳情查看API。
 220.對象數組保存的詩引用,基本類型數組保存的是數值!
 221.布爾型自動被初始化成false。
 222.在java中不需要擔心爲數組負責---只要你需要它,它就會一直存在,當你使用完後,垃圾回收期會清理掉它!
 223.Arrays.fill(數組名,填充值)允許用一個固定值填充數組!System.arrayopy(數組1,開始位置,數組2,開始值,複製長度)允許把二中指定長度的值複製給一。
 224.數組的equals:數組長度相同,相同位置上的元素相同!
 225.程序設計的基本目標是“是不變的事物與會發生變化的事物分離”,通過回調技術可以將會發生變化的代碼分離出來,然後由不會變化的代碼回調會發生變化的代碼!
 226.Map中有內置的排序,若Map中的順序對你很重要,應該使用LinkedHashSet或LInkedHashMap。
 227.注意:Clooection及List,Set添加對象都用add,Map中用put方法!
 228.注意:編譯器隱式地支持String類型的轉型,因爲toString的存在,打印容器中的對象時都是調用對象的toString方法,因此若想打印出個性的內容建議在toString上做文章!
 229.無形中產生的遞歸:public class Recursion {
                                public String toString() {
                                   return “Recursion”+ this;
                                }
                               List v = new ArrayList();
                              for(int i=0;i<3; i++) {
                               v.add(new Recursion());
                            System.out.println(v);                             
                              }
                                
                                   }
                            }
  這樣會得到一個遞歸!應爲打印V時會調用toStirng,當在toStirng中遇到this後,編譯器會嘗試把它轉爲toString 這樣無形的形成了一個遞歸!
 230.遞歸:允許一個方法在自己的內部調用自身!
 231.接口的優美之處在於如果你決定改變當前的實現,只需要在創建的位置做些修改!
 232.一個List可以生成ListIterator,使用它可以從兩個方向遍歷ArrayList,也可用於List中間插入和移除元素!ArrsyList查快改慢;LinkedList改快查慢!
 233.LinkedList有addFirst,addLast,removeFirst,removeLast,getFirst,getLast這些方法(沒有在任何接口或基類中定義過)使得LinkedList可以當做堆棧,隊列,雙向隊列使用!

 

 

 234.節點流就是直接插在文件上的流,相比,套在節點流或處理流上的流稱作處理流!
 235.良好的編程習慣,在關閉流之前,先調用flush方法!把緩衝的數據都提取到目的地!flush方法貌似只是在輸出流中才有!
 236.管道是線程與線程之間的通訊!
 237.注意:用FileInputStream時,打印讀取數據時要把in.read()賦值給一個int數,然後打印是把int數轉換成char型!不知爲何!直接打印in.read()有落差!
 238.奇怪:用FileInputStream讀取漢字然後再用FileOutputStream寫出去!能獲得完整的文件!但是打印的時候卻得到亂碼!

 239.當用ByteOutputStream讀取字節數組中的數據時注意“先寫先讀”隊列順序!
 240.DataStream處理流,用來處理java的基本數據類型!
 241.經典的輸入流包裹:BufferedReader包裹InputStreamReader包裹System.in
 242.Print流比較特殊!PrintWriter和PrintStream都屬於輸出流,分別針對與字符和字節!PrintWriter和PrintStream不用拋異常!此外PirntWriter和PrintStream都有自動的flush功能!
 243.若想要把一個對象序列化!那該類必須實現serializable接口!
 244.當需要用Object流來讀取或寫入一個對象時!務必要實現Serializable接口!否則對象不能被序列化!注意:transient用來修飾成員變量!用它修飾的變量在程序序列化時不予考慮!Externalizable接口繼承自Serializable用來實現程序員控制的對象序列化過程!
 245.UTF-8字符串省空間!因此在網絡上傳輸時通常採用UTF-8;
 246.注意sleep方法時靜態方法調用方式:Thread.sleep(時間)!join方法也需要拋異常InterrputedException但是join方法感覺挺乾淨!簡潔!
 247.在單核cpu的機器上,線程的優先級表現的很好!
 248.原子性的輸出:最小單元的輸出!不可再分!
 249.注意:在方法前返回類型前加synchronizaed當該方法被調用時鎖定調用該方法的對象的引用!並非鎖定該方法!
 250.沒鎖住的方法不能wait!否則報錯!
 251.Wait時別的線程可以訪問鎖定對象,調用wait方法的時候必須鎖定該對象;Sleep時別的線程也不可以訪問鎖定對象!Wait屬於Object類,Sleep屬於Thread類!
 252.網絡編程時,記住,邊寫server邊寫client,起程序的時候先起server再起client!

 253.聊天程序總結:首先,要得到socket的InputStream和OutputStream,注意在用InputStreamReader或者DataInputStream包裹時包裹的是getInputStream或OutputStream而非流的名字!第二:Wile循環中注意判斷條件是“不等於某字符串時開始循環”注意加否定歎號!第三:由於進出順序!當Client結束是字符串先在Client驗證,所以Client先結束,同時Server端出現異常!最後我把異常給吞噬掉!無奈,目前沒想到相關解決辦法!
 254.注意順序:Server:讀C,驗C,寫C,讀S,寫S,發S,再讀C;Client:讀C,驗C,寫C,讀S,寫S,再讀C!
 255.UDP根本無所謂客戶端,服務端,所謂的Server就是用DatagramSocket new出來的對象裹一個端口,接收的時候用對象的receive方法接收一個DatagramPacket的對象,對象裏裹得是一個字節數組!byte型的!長度自己定義!打印接收的數據的時候就new一個String然後調用那個複製的方法,注意,方法中的長度參數要用getLength!所謂的client也是一個DatagramSocket一個DatagramPacket,注意,Packet對象在裹字節數組的時候要在最後new 一個InetSocketAddress後邊寫上IP跟端口!用DatagramSocket對象的Send方法發出去就行了!注意new DatagramSocket的時候加上一個端口號!是用來發送的!
 256.注意跟UDP通訊用的流最多的就是ByteArrayInput/OutputStream和DataInputStream/OutputStream


 257.進入GUI編程!加油加油!
 258.要想在JFrame裏使用setBackground方法還得引入awt包!
 259.Frame裏的setLayout方法很重要,當顯示不正常時可以檢查此方法!切記切記!
 260.注意:FlowLayout是Panel類默認的佈局管理器!FlowLayout佈局管理器的默認對齊方式時居中!
 261.BorderLayout是Frame的默認佈局管理器!
 262.若不指定組件的加入部位,則默認加入到center區,每個區域只能加入一個組件,若加入多個,則先前加入的會被覆蓋!
 263.注意:f.add(null,BorderLayout.WEST);這種做法是不對滴!
 264.監聽器又叫鉤子函數,回調函數!
 265.注意:pack方法要寫在Frame的add方法後!這樣才能根據add進去的compont默認設置Frame的大小!
 266.getSource方法獲得的是發生事件的對象的引用!注意已經向上轉型爲ActionEvent類型!具體使用的時候需要再向下強制轉型到具體的compont!
 267.注意setEcohChar方法中間的參數是char型,用單引號包裹!而且JTextField裏沒有該方法!
 268.注意import 包的時候有個類叫java.awt.Event不是監聽器類,監聽器類是java.awt.event切記切記!
 269.持有對方引用!如果A類中在B類有許多需要訪問成員變量,那麼可以使用持有對方引用!用法:在B類中new一個A類的對象,然後在B類的構造裏作爲參數傳給B的對象,這樣在B中可以用這個引用隨意訪問A的成員變量!很優雅的訪問方案!

 270.Graphics類,在Java裏控制畫圖,使用此類時只需在類中重寫paint方法,裏面自動生成一個Graphics 的對象,利用這個對象結合Graphics中的方法可以畫出相關程序,注意Color c = g.getColor 最後 g.setColor = c 這樣回覆現場!把畫筆顏色返還給畫筆!
 271.調用repaint方法,強制frame重畫,這是一種雙緩衝模式! 調用repaint時內部調用update方法,再調用paint得到畫筆!
 272.實現鼠標監聽器的時候實現mouseAdapter類可以隨意按需要重寫的響應鼠標方法!如果實現的是MouseListener接口就要全部重寫裏面的 方法!
 273.System.exit(0)表示正常退出,System.exit(-1)表示異常退出!
 274.什麼時候使用匿名類:放在匿名類中的邏輯簡單,不需要經常變動!

 275.LinkList具有能夠直接實現棧的所有功能的方法,棧:LIFO 後進先出,最後壓入棧的元素最先彈出棧。
 276.LineInputStream(InputStream)可調用getLineNumber和setLineNumber方法。
 277.可以用內部類啓動線程,現在外圍類裏創建一個內部類的引用,然後再把內部類繼承到Thread或實現Runnable方法,把start寫在內部類的構造裏,內部類裏重寫run方法,外圍類裏把先前內部類的引用new在一個方法裏面,通過外部類對象調用方法再調用Start來實現線程的啓動!
 278.用匿名內部類更好:外圍類提供一個thread對象,在外圍類的構造裏t = new Thread(name) {public viod run(){}};
 279.設計Timer類的目的就是承擔大量併發調度任務,所以它能成爲很有用的工具。
 280.setDaemon(true)將線程設爲後臺線程,isDaemon()檢測線程是否後臺,作用在實現了Thread的導出類中,必須聲明在Start之前。
 281.要控制對共享資源的訪問,得先把它包裝進一個對象,然後把所有要訪問這個資源的方法標記爲synchronized 也就是說:一旦某個線程處於一個標記爲synchronized的方法中,那麼在這個線程從該方法返回之前其他所有要調用類中任何標記爲synchronized方法的線程都會被阻塞。
 282.針對每個類也有一個鎖,所以synchronized statci方法可以在類的範圍內防止對static數據的訪問。
 283.最安全的同步方針:1.如果要對類中的某個方法進行同步控制,最好同步所有方法,如果忽略了其中那個一個通常很難確定這麼做是否會有負面影響。2.只應在使用性能評價工具正式了條同步控制卻是是性能瓶頸的時候纔會解除同步。
 284.Sleep方法不好釋放鎖, wait notify notifyAll方法會自動釋放鎖,所以上述方法必須使用在同步方法裏。
 285.在run中用一個flag布爾型來控制線程的返回在檢查關閉條件符合後修改flag來實現線程結束!
 286.對象設計的五個階段:1.發現對象;2.對象的組合;3.系統的構建; 4.系統擴展; 5.對象重用!
 287:
           建議:設計階段:: 1.優雅終將得到回報!2.先能運行,再求速度!3.謹記“分而治之”的原則!4.區分類的編寫者和使用者!5.編寫類的時候,類的名稱要十分清晰,不需要註釋也能理解!6.分析和設計必須使用系統中的類,它們的公共接口以及雷之間(尤其是與基類之間)的關係必須達到最少!7.儘量讓所有東西自動化!8.在編寫類之前先編寫測試代碼,以驗證這個類是否設計完備!9.所有軟件設計中的問題,都可以通過“引入額外的間接概念層次”得到簡化!10.引入的間接概念層次要有意義!11.儘可能使類原子化:::a.複雜的switch語句---考慮使用多態;b.有許多發雜的方法,各自處理類型極爲不同的操作---請考慮劃分成不同的類;c.有許多成員變量,用來表示類型極爲不同的屬性---請考慮劃分成不同的類。12.當心冗長的參數列表!13.不要一再重複!14.小心switch語句和if-else子句!15.從設計觀點來看,要找出變動的因素,使它和不變的因素分開!16.不要依靠子類化來拓展基礎功能!17.盡少意味着更多!18.大聲朗讀你的類,確保它們能夠編譯通過!19.在判斷應該使用繼承還是組合的時候,考慮一下是否需要向上轉型成基類型!20.採用字段表示數值的變化,使用方法覆蓋來變現動作的變化!21.小心重載! 22.使用異常體系!23.有時候僅僅使用聚合就能解決問題!24.從客戶端程序員和程序維護者的角度進行思考!25.當心“巨型對象綜合症”26.如果你只能採用某種彆扭的方式才能實現某個功能,清將其抽象成服務,並侷限在某個類內部!27.對象不應僅僅用來持有數據!28.在原有類的基礎上編寫基類時,首先應考慮組合!30.使用繼承和方法覆蓋來表達行爲上的差異,使用字段來表示狀態的變化!31.當心“變異性”! 32.注意繼承期間的“限制”!33.使用設計模式來消除那些“純粹的功能性代碼”!34.當心“分析癱瘓”的情況!35.當認爲自己已經獲得了一個優秀的分析,設計或實現時,進行一次全面評審!

  實現階段::1.一般來說,清遵守Sun的程序編寫習慣!2.無論使用何種編寫風格,如果你的團隊(或者公司)能夠加以標準化,那麼的確會帶來顯著效果!3.遵守標準的大小寫規範! “包”是一個特列!4.不要爲私有字段名稱加上你自己的“修飾”符號!5.編寫通用性的類時,清遵守標準形式。包括定義equals hashCode toString  clone並實現Comparable和Serialiable接口!6對於那些“獲得或改變私有字段值”的方法,清使用javaBeande "get" "set" "is" 等命名習慣!7.對於你編寫的每一個類,清使用JUnit爲他編寫測試!8.有時需要通過繼承才能訪問基類的受保護成員!9.應避免純粹爲了提高執行速度而採用final方法!10.如果兩個類在功能性上產生了慣量(比如容器和迭代器),那麼請試着讓一個類成爲另一個類的內部類!11.在任何時候,都要警惕那些互相之間高度耦合的類!考慮一下使用內部類爲程序編寫維護帶來的好處!12.不要跳入過早優化的陷阱!13.儘可能縮小對象的作用域,這樣對象的可見範圍和生存期也都儘可能地小!14.使用Java標準庫提供的容器!15.對於一個健壯的程序而言,每一部分都必須健壯!16.寧可在編譯期發生錯誤,也不要錯誤發生在執行期!17.當心冗長的方法定義!18.儘量使用private關鍵字!19.大量使用註釋,並使用javadoc的“文檔註釋語法”來生成程序的文檔!20.避免使 用“魔術數字”21.在編寫構造器時,請考慮異常!22。在構造器中只做必要的動作!將對象設定爲正確狀態!23.客戶端程序員用完對象之後,將對象設定能夠爲正確狀態!24.客戶端程序員用完對象之後,如果你的類需要任何清理動作,請將此動作放到一個精心定義的方法中!24.finalize方法的職責職能是爲了調試的目的而檢查對象的“終結條件”!25.如果對象在某個特定範圍內必須被清理(而不是作爲垃圾被回收)請先初始化對象如果成功的話嗎,立刻進入一個帶有finally子句的try塊,在finally子句中進行清理動作!26.在繼承的時候如果覆蓋了finalize地方法,要記得調用super.finalize! 27.當你編寫固定大小的對象容器時,它們要能夠被傳送給一個數組!28.優先選擇接口而不是抽象類!29.爲了避免十分令人泄氣的經歷,清檢查類路徑,確保所有爲放進包裏的類的名稱互不相同!30.注意無心的重載錯誤! 31當心過早優化!32.記住:記住代碼被閱讀的時間多於它被編寫的時間!

 

 

 

 

 

   SWING SWING SWING
 1.在頂層容器中也可以添加菜單組件,而菜單組件一般是放在頂層容器中,和內容面板是並列的!
 2.在JFrame中添加面板可以用add(),但是JFrame類自有的方法時setContentPane()
 3.關於菜單欄(JMenuBar)包括JMenu JMenuItem,JMenu構造器接收String爲其指定名稱,然後JMenuItem接受字符串爲其命名,Bar包裹Menu,Menu包裹Item,Item對象有addSeparator爲其添加間隔線!

 4.添加組件的時候按照自下而上的順序!編譯器貌似很笨!

 


   正則表達式
 1.當匹配一個\時,必須用四個\來匹配,若用兩個會報錯!因爲java中\\表示一個\
 2.在匹配正則表達式時,如果字符串已經到結尾還調用find方法,編譯不會報錯!只會輸出false結果!
 3.matches方法永遠匹配整個字符串!find方法從目標字符串中找字串!lookingAt方法只是從字符串的起始位置匹配,符合則返回true!
 4.start,end方法返回的字符串下標都是左閉右開的!
 5.注意:布爾型返回型的方法常用作循環判斷條件!
 6.正則表達式的分組:從表達式的左起,有幾個左括號就是第幾組!
 7.表達式裏的點號默認不匹配換行符!


   數據結構
 1.雜亂的數據不能表達和交流信息!
 2.數據之間是有內在聯繫的!
 3.數據之間是有聯繫的!
 4.在某種數據結構上可定義一組運算!
 5數據結構主要研究的內容:研究數據的各種邏輯結構,物理結構以及他們之間的相應聯繫;並對各種結構定義相應的各種運算;設計出相應的算法;分析算法的效率!
 6.數據元素是數據的一個個體!數據對象是數據的一個子集!
 7.數據項是數據具有意義的最小單位!
 8.數據結構就是有結構的數據元素的集合!
 9.數據結構就是數據元素及其相互關係的集合!
 10.邏輯結構:數據元素之間的結構關係!
 11.物理結構:數據結構在機內的表示!
 12.算法:算法是一個有限的指令集,循環指令流可以完成特定的功能!
 13.算法的基本特性:a.有窮性:算法經有限步後結束!b.確定性:下一步必須是明確的!c.可行性:每一部是可執行的!
 14.算法與程序的區別:算法是解決問題的一種方法或一個過程,考慮如何將輸入轉換成輸出,一個問題可以有多種算法!程序時用某種程序設計語言對算法的實現!
 15.程序可以是無窮的,例如OS,算法是有窮的!程序可以是錯誤的,算法必須是正確的!程序是用程序設計語言描述,在機器上可以執行!算法還可以用框圖,自然語言燈方式描述!
 16.算法是給人看的,程序是給機器看的!
 17.程序設計語言+自然語言描述的算法叫僞代碼!
 18.衡量算法的標準:A.運行所花費的時間(算法的時間特性)B.所佔用的存儲空間大小(算法的空間特性)C.其他(可讀性,易調性,健壯性)!
 19.算法的時間複雜度:T(n) = o(f(n)) 其中,n爲算法的語句頻度,即語句可執行的最大次數,也叫規模!o()爲算法的同階無窮大!如:x = x+1; 語句頻度爲 1 時間複雜度爲O(1) 常數階; for(int 1 = 1; i<n; i++) {x = x+1;} 語句頻度爲n+1(因爲當i = n+1時雖然已經跳出for循環,但是還要進行一次判斷所以這裏去語句的最大循環次數)故時間複雜度爲O(n) 線性階; for(int i = 1; i<n; i++) {for(int j=1; j<n; j++) {x = x+1}} 語句頻度爲n(n+1) 所以時間複雜度爲o(n*n) 平方階!
 20.注意語句頻度爲算法中重複次數最多的一個語句的次數即N!時間複雜度是針對某個算法而言的,而不是對於那條頻度最高的語句而言的!
 21.算法與時間複雜度的關係:不必追求高效算法,低效算法可由高效計算機彌補的看法是錯誤的!當算法的時間複雜度大到一定程度,該算法在效率相差很大的機器上運行的時間是差不多的!
 22.線性表是N個數據元素的有限序列,記爲 L = (a1,a2,……an)
在線性表中,數據元素之間的關係是:ai-1 領先於ai ,ai領先於ai+1; 稱ai-1是ai的直接前驅元素;ai+1是ai的直接後繼元素;除a1外,每個元素有且僅有一個直接前驅元素,除an外,每個元素有且僅有一個直接後繼元素,線性表中數據的個數n(n>=0)稱線性表的長度,當n=0時,稱爲空表!
 23.線性表的基本運算:1.INITIALTE(L)初始化操作;2.LENGTH(L)求長度函數;3.GET(L,i)取元素函數,類似的數組中一個遊標i 叫做該線性表的位序;4.PRIOR(L,elm)求前驅函數;5.NEXT(L,elm)求後繼函數;6.LOCATE(L,x)定位函數,返回X在表中第一次出現時的位序,若不存在返回0;7.前插操作INSERTE(L,i,b)表示把b插入到位序i前邊!8.DELETE(L,i) 刪除操作;9.判空表函數(L),若表L爲空則返回真!10.CLEAR(L)表置空操作,將L置爲空表!
 24.注意:線性表的所有函數都需要程序員自己實現,因爲線性表都是自己定義的!所以函數更需要自己定義了!
 25.算法思想是指導編寫算法的,算法是指導編寫程序的!
 26.數據在計算機中的存儲結構包括:順序存儲結構和鏈式存儲結構,所有的數據在計算機中都是這樣實現存放的!順序存儲結構是一種物理結構!
 27.線性表的順序存儲結構特點:a.邏輯上相鄰的元素,其物理位置也相鄰;b.可隨機存取表中任一元素;c.必須按最大可能的長度預分存儲空間存儲空間利用率低,表的容量難以擴充,是一種靜態存儲結構!d.插入刪除時,需移動大量元素,平均移動元素爲n/2!
 28.鏈式存儲結構:由節點組成,每個節點包括數據域和指針域,指針域指向下一個節點的數據域!每個節點的指針域只保存自己的直接後繼元素的指針域!最後一個節點的指針域爲空!若將該空指針域指向第一個節點的數據域,則形成一個循環鏈表!
 29.我們定義的單鏈表都是定義的指針,頭指針,單鏈表中的任何一個數據都要通過頭指針來找到!頭指針能夠唯一的標識一個單鏈表!
 30.單鏈表的判空條件是頭指針爲空!
 31.其實頭節點的引入就是爲了給鏈式存儲結構的第一個數據元素DE中的數據域添加一個引用(指針)!

 32.線性錶鏈式存儲結構的特點:a.邏輯上相鄰的元素,其物理位置不一定相鄰;元素之間的鏈接關係由指針域指示!b.鏈表是非隨機存取存儲結構;對鏈表的存取必須從頭指針開始!c.鏈表是一種動態存儲結構;鏈表的結點可以調用new()申請和dispose()釋放!
d.插入刪除運算非常方便;只需修改相應指針值!
 33.循環鏈表的判空條件:H = H↑.next;
 34.雙向鏈表的判空條件:L↑.priou = L↑.next = NIL;
 35.雙向循環鏈表的判空條件:L↑.priou = L↑.next = L;
 36.當接到實際問題編寫算法時,首先應該選擇數據結構,然後選擇數據結構的邏輯結構,然後是物理結0:16 2010/3/4構,最後是算法的實現!
 37.鏈表中的插入原則:從後往前接,如果從前往後接,當接到後面的時候後繼元素的直接前驅元素的後繼已經被賦值給了插入元素,而原來的後繼已經丟失,從而造成斷鏈!切記切記!
 38.棧是插入和刪除操作限定在表尾進行的線性表!
 39.棧是操作受限制的線性表!
 40.線性表的應用:一元多項式求值!
 41.棧的應用:表達式求值,遞歸!
 42.遞歸過程的特點:是程序設計的一個強有力的工具,它具有結構清晰,程序易編,易讀,易調試,程序正確性容易證明!但是運行效率低!
 43.遞歸原理:基本原理是重複地把問題轉化爲與原問題相似的新問題,知道問題可解決爲止!
 44.關鍵點:a.用較簡單的新問題來表示較複雜的原問題,例如:n! = n(n-1)!,或n! = (n+1)!/(n+1) 前者(n-1)! 較原問題n! 簡單,可行;而後者(n+1)! 較n! 更復雜,不可行!b.不能產生自己調用自己的無窮序列,即必須有一個遞歸調用序列的“出口”,來種植遞歸調用!
 45.實現:遞歸過程都是通過棧來實現的,並且所有遞歸算法都可以通過棧改寫爲非遞歸算法!
 46.隊列(quene)是限定在一端插入,另一端刪除的線性表。允許插入的一端叫隊尾(rear),允許刪除的一端叫對頭(front),不含元素的空表成爲可空隊列,隊列的運算特性是先進先出!
 47.隊列的基本運算:ENQUEUE(Q,x) 入隊操作,隊尾插入操作!DLQUEUE(Q)出隊操作!GETHEAD(Q) 取隊頭元素且不刪除!CURRENT-SIZE(Q) 求長度操作!
 48.本來隊列中元素沒有滿,卻不能添加新元素的現象叫做“假溢出”!
 49.隊列的判空:q.front = q.rear
 50.循環隊列解決“假溢出”問題,循環隊列的判空與判滿一樣!
 51.循環隊列順時針旋轉!
 52.入隊操作:append := rear"++"then append job; pop := remove job then front"++"注意“++”完成後要除以隊列的maxsize取餘!i = (i + 1)%max
 53.解決循環隊列的判空與判滿條件一致的問題:1.在隊列中預留一個空位;2.設定一個標誌,沒元素時爲0.有元素時設爲1!3.設置一個數字計數器!4.讓front和rear等於一個不可能等於的值!
 54.串的概念:n個字符的有限序列!求字串在串中的起始位置稱爲字串定位或模式匹配!
 55.順序存儲結構時首先要確定數據的最大存儲長度!
 56.串的鏈式存儲結構叫做塊鏈結構!因爲串可能將若干個元素封裝成一個節點!不一定只是一個數據元素!、
 57.數組和廣義表是結構發生了變化的線性表!是線性表的一種拓展!
 58.稱非空表的第一個元素爲表頭,其餘元素組成的表稱爲表尾!所以表頭可以是單元素或表,但是表尾必須是一個表!
 59.矩陣的壓縮存儲:給多個值相同的元素只分配一個空間,或者對值爲零的元素不分配存儲空間!
 60.適用於壓縮存儲方式的特殊矩陣:對稱矩陣,對角矩陣,稀疏矩陣!
 61.廣義表的兩類存儲結構:1,表頭表尾鏈結構,有兩類節點::表結點,單元素結點!2.同層結點鏈結構!
 62.數據結構分爲線性結構(線性表,棧,隊列等)非線性結構:至少在一個數據元素有不止一個直接前驅或後繼(樹,圖等)!

 

 


數據結構:
  樹和二叉樹:
 1.樹的表示法:分支圖表示法,嵌套集合表示法,廣義表!分支圖表示法最直接!
 2.樹的結點:包含一個DE和指向其子樹的所有的分支!
 3.結點的度:一個節點擁有的子樹的個數,
我們稱爲結點的度,度爲零的結點稱爲葉結點。
 4.樹的度:樹中所有結點的度最大值(Max(D(I)).
含義:樹中最大分支數爲樹的度! 
 5.注意:樹的度不是樹中所有結點的集合!而是最大值!
 6.結點的層次及樹的深度:根爲第一層,根的孩子爲第二層
,若某結點爲第K層,則其孩子爲K+1層,樹中結點的最大層次稱爲樹的深度或高度!
 7.森林:是m(m>=0)棵互不相鄰的樹的集合,森林與樹概念相近
,相互很容易轉換!
 8.樹的度是指它孩子的分支!
 9.二叉樹是結點數爲0或每個結點最多隻有左右兩棵子樹的樹,
二叉樹是一種特殊的樹
 10.特點:每個結點最多隻有兩顆子樹,即不存結點度大於2的結點;子樹有左右
之分,不能顛倒!
 11.二叉樹和度爲二的樹的區別:結點孩子的個數,孩子的順序!
 12,二叉樹的性質:1,在二叉樹的第i層上只多有2^i-1個結(i>=1)
 13.深度爲k的二叉樹之多有2的k次方減1個結點(k>=1) (深度一定,二叉樹的最大結點數也確定)
 14.二叉樹中,終端結點數n0與度爲2的結點數n2有如下關係:n0 = n2 +1
 15.滿二叉樹:深度爲K,且有2的k次方減1個結點的二叉樹!特點:
 a.每一層上結點數都達到最大;b.度爲1的結點n1 = 0!
 16.結點層序編號方法:從根結點起從上到下逐層(層內從左到右)對
二叉樹的結點進行連續編號!
 17.完全二叉樹:深度爲k,結點數爲n的二叉樹,當且僅當每個結點的標號
都與相同深度的滿二叉樹中從1到n的結點一一對應時,成爲完全二叉樹!
 18.哈夫曼樹是帶權路徑長度最短的二叉樹!
 19.圖分爲有向圖(Directed graph),無向圖(Undirected graph)
 20.設n爲定點數,e爲邊或弧的條數,對Undirected graph有:0<=e<=n(n-1)/2,
對於Drieced graph 有:0<=e<=n(n-1)!
 21.完全圖(Complete graph):邊達到最大的圖!
 22.無向完全圖:邊數爲n(n-1)/2的無向圖;有向完全圖:邊數達到n(n-1)的圖!
 23.權:與圖的邊或弧相關的數;網:邊或弧上帶有權值的圖!
 24.定點的度TD(V):無向圖:爲依附於定點V的邊數;有向圖:等於以頂點V爲
弧頭的弧數(稱爲V的入度,記爲ID(V))與以頂點V爲弧尾的弧數(稱爲V的出度,記爲OD(V))之和,即:TD(V)
 = ID(V) + OD(V)
 25.路徑長度:路徑上邊或弧的數目!
 26.簡單路徑:路徑中不含相同頂點的路徑!
 27.迴路或環:首尾頂點相同的路徑,稱爲迴路或環!
 28.頂點連通:若頂點V到頂點V'有路徑,則稱頂點V與V'是連通的!
 29.無向連通圖:若無向圖中任意兩個頂點VI,VJ都是連通的,則稱該圖是連通圖(vi<>vj)
 30.有向連通圖:若有向圖中任意兩個頂點vi ji都存在從vi到vj和從vj到vi
的路徑,則稱該圖爲強連通圖(vi<>vj)
 31.無向圖連通分量:無向圖中極大連通子圖,稱爲連通分量!
 32.有向圖強連通分量:有向圖中極大強連通圖,稱爲強連通分量!
 33.生成樹:設無向圖G是含有n個頂點的連通圖,則圖G的生成樹是含有n個頂點,且只有n-1條邊的連通子圖!
 34.圖的存儲結構:鄰接矩陣!
 35.圖的遍歷算法:深度優先搜索算法,廣度優先搜索算法!

 36.生成樹的三大要素:n個頂點,n-1條邊,連通!
 37.生成樹代價:對圖中每條邊賦予一個權值(代價),則構成一個網,網的生成樹
G'=(V.{T})的代價是T中各邊的權值之和,最小生成樹就是網上所有可能的生成樹中,代價最小的一類生成樹!
最小生成樹也不一定唯一,但是其代價肯定是相等的!

 

 

性質4:結點數爲n的完全二叉樹,其深度爲log2n向下取整+1!
性質5:在按層序編號的n個結點的完全二叉樹中,任意一結點i(1<=i<=n)有:
 a.i = 1時,結點i是樹的根;否則(i>1),結點i的雙親爲結點i/2向下取整;
 b.2i>n時,結點i無左孩子,爲葉結點;否則,結點i的左孩子爲結點2i;
 c.2i+1>n時,結點i無右孩子;否則,結點i的右孩子爲結點2i+1!
性質6:含有n個結點的二叉鏈表中,有n+1個空鏈域!
1.遍歷二叉樹:遍歷二叉樹是指按一定的規律對二叉樹的每一個結點,訪問且僅訪問一次的處理過程!
2.訪問時一種抽象的操作,是對結點的某種處理,例如:求結點的度,層次,打印結點的信息或做其他的工作!
3.遍歷的次序:若設二叉樹根爲D,左子樹爲L,右子樹爲R,並限定先左後右,則有以下三種遍歷次序:LDR 中序遍歷; LRD 後序遍歷; DLR 先序遍歷!(是根據D的順序而定的)!左子樹始終先於右子樹!

 

圖:
 1.設無向圖中頂點數爲n,邊數爲e,則它的鄰接表需要n個頭結點和2e個表結點!若爲有向圖,則它的鄰接表需要n個頭結點和e個表結點!
 2.與無向圖的鄰接表結構一樣,只是在第i條鏈表上的結點是以vi爲弧尾的各個弧頭頂點!第i條鏈表上的結點,爲vi的出度!
 3.爲了方便求vi的入度,建立了有向圖的逆鄰接表,只是在第i條鏈表上的結點表示以vi爲弧頭的各個弧尾頂點!
 4.鄰接表計算出度容易,入度難,逆鄰接表計算入度容易,出度難!
 5.最小生成樹的性質MST:設N=(V,{E})是一個連通網,U是頂點集V的一個非空子集,若(u,v)是一條具有最小權值的邊,其中u屬於U,v屬於V-U即(u,v)= Min{cost(x,y)|x屬於U,y屬於V-U,則比存在一顆包含邊(u,v)的最小生成樹!
 6.最小生成樹的著名算法:普瑞姆算法!克魯斯卡爾算法!共同利用MST特性! 7.AOV 網可以解決如下兩個問題:1.判斷工程的可行性,顯然,有迴路,整個工程就無法完成!2.確定各項活動在整個工程執行中的先後順序!稱這種先後順序爲拓撲有序序列!
 8.拓撲排序的算法步驟:1.在AOV網中,選取一個沒有前驅的頂點輸出;2.刪除該頂點和所有以它爲弧尾的弧;3.重複以上兩步,直到AOV網中全部頂點都已輸出(得到拓撲有序序列)或者,圖中再無沒有前驅的頂點(AOV網中有環)
 9.拓撲排序是一種對非線性結構的有向圖進行線性化的重要手段!
 10.關鍵路徑的對象是AOE網!
 11.AOE網:有向圖中,頂點表示事件,弧表示活動,弧上的權表示完成該活動需要的時間,則稱這類有向圖爲邊表示活動的網(AOE網)
 12.AOE網中僅有一個入度爲0的事件,稱爲源點,表示工程的開始;也僅有一個出度爲0的事件,稱爲匯點,表示工程的結束!每一事件V表示以它爲弧頭的所有活動已經完成,同時,也表示以它爲弧尾的所有活動可以開始!
 13.AOE網可解決的問題:1.估算工程的最短工期(從源點到匯點至少需要多少時間)2.找出哪些活動是影響整個工期進展的關鍵!
 14.路徑長度:路徑上各活動持續時間的總和,即:路徑上所有弧的權值之和)
 15.關鍵路徑:從源點到匯點直接按路徑長度最長的路徑(不一定是唯一的)
 16.求AOE網的關鍵路徑:a.先算各個事件(頂點)的最短髮生時間,前結點時間+路徑上的權值!取最大值!事件的最遲發生時間,從後往前算,取最小值!每個活動的最早發生時間就是它的弧尾時間!
 17.查找表(table):由同類型的DE或記構成的集合!
 18.靜態查找表的第三個查找算法:索引表查找法!(分塊查找法)
 19.動態查找表的特點:表的結構在查找過程中試可以變化的!
 20.二叉排序樹:BST 或者是一棵空樹,或者是具有如下性質的BT:A.若左子樹非空,則左子樹上所有結點的值均小於根結點的值;B.若右子樹非空,則右子樹上所有結點的值均大於根節點的值;C.左右子樹也爲BST!
 21.不同關鍵字得到同一地址的現象,稱爲衝突!
 22.幾種哈希函數:直接哈希函數(選擇關鍵字的一個線性函數作爲哈希地址)數學分析法:取key中數字均勻分佈的作爲哈希地址!平方取中發:取關鍵字平方後的中間幾位作爲哈希地址!
 23.摺疊法:將關鍵字分割成位數相等的幾部分,取這幾部分的疊加和,捨去高位的進位,位數由存儲地址的位數確定!相加時有兩種方法:移位疊加法:將每部分的最後一位對齊,然後疊加;另一種是間界疊加法:即將關鍵字看做一紙條,從一端向另一端沿間界逐次摺疊,然後對齊相加!
 24.除留餘數法:取關鍵字被某個不大於哈希表長m的數p除後的餘數作爲哈希地址!
 25.隨機數法:選擇一個隨機函數,取關鍵字的隨機函數值作爲它的哈希地址!
 26.處理衝突的方法:開放定址法!再哈希法!鏈地址法!公共溢出區法!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章