1. 程式人生 > 實用技巧 >Java基礎總結大全

Java基礎總結大全

Java基礎總結大全

一、基礎知識:
1、JVM、JRE和JDK的區別:
JVM(Java Virtual Machine):java虛擬機器,用於保證java的跨平臺的特性。
java語言是跨平臺,jvm不是跨平臺的。
JRE(Java Runtime Environment):java的執行環境,包括jvm+java的核心類庫。
JDK(Java Development Kit):java的開發工具,包括jre+開發工具

2、環境變數path和classpath的作用是什麼?
(1)path是配置Windows可執行檔案的搜尋路徑,即副檔名為.exe的程式檔案所在的目錄,
用於指定DOS視窗命令的路徑。
(2)Classpath是配置class檔案所在的目錄,用於指定類搜尋路徑,JVM就是通過它來尋找該類的class類檔案的。

3、變數有什麼用?為什麼要定義變數?什麼時候用?
答:變數的作用:用來儲存資料。
為什麼要定義變數:用來不斷的存放同一型別的常量,並可以重複使用

4、&和&&的區別?
答:(1)&&會出現短路,如果可以通過第一個表示式判斷出整個表示式的結果,則不繼續後面表示式的運算;
只能操作boolean型別資料;
(2)&不會出現短路,將整個表示式都運算。既可以操作boolean資料還可以運算元。

5、標示符命名規則:
由數字(0-9),大小寫英文字母,以及_和$組成。
不能以數字開頭。
不能使用關鍵字來自定義命名。

6、資料型別:
(1)基本資料型別(4類8種):
整數型別:byte、short、int、long
浮點數型別:float、double
字元型別:char
布林型別:boolean(ture false)
(2)引用資料型別:

介面
陣列

7、型別轉換
精度從高到低 double float long int short(char) byte
(1)自動型別轉換 將一個低精度---高精度
(2)強制型別轉換 將一個高精度---低精度(精度會下降)

8、java語言的三種技術架構
J2EE:企業版
是為開發企業環境下的應用程式提供的一套解決方案。
該技術體系中包含的技術如 Servlet、Jsp等,主要針對於Web應用程式開發。
J2SE:標準版
是為開發普通桌面和商務應用程式提供的解決方案。
該技術體系是其他兩者的基礎,可以完成一些桌面應用程式的開發。
比如Java版的掃雷。
J2ME:小型版
是為開發電子消費產品和嵌入式裝置提供的解決方案。
該技術體系主要應用於小型電子消費類產品,如手機中的應用程式等。

9、java的跨平臺性:
通過Java語言編寫的應用程式在不同的系統平臺上都可以執行。
跨平臺的原因:
只要在需要執行java應用程式的作業系統上,先安裝一個Java虛擬機器(JVM Java Virtual Machine)即可。
由JVM來負責Java程式在該系統中的執行。

10、有符號資料的表示法(次重點)
原碼,反碼(原碼取反),補碼(反碼+1)。

11、函式
定義:函式就是定義在類中的具有特定功能的一段獨立小程式。
特點:
定義函式可以將功能程式碼進行封裝
便於對該功能進行復用
函式只有被呼叫才會被執行
函式的出現提高了程式碼的複用性
對於函式沒有具體返回值的情況,返回值型別用關鍵字void表示,
那麼該函式中的return語句如果在最後一行可以省略不寫。
函式的應用兩個明確:
明確要定義的功能最後的結果是什麼?
明確在定義該功能的過程中,是否需要未知內容參與運算

12、過載:
概念:在同一個類中,允許存在一個以上的同名函式,只要它們的引數個數或者引數型別不同即可。
特點:與返回值型別無關,只看引數列表(引數型別以及引數個數)。
好處:方便於閱讀,優化了程式設計。

13、陣列:
概念:同一種資料型別的集合。
好處:可以自動給陣列中的元素從0開始編號,方便操作這些元素。

14、記憶體結構:
棧記憶體:用於儲存區域性變數,當資料使用完,所佔空間會自動釋放。
堆記憶體:陣列和物件,通過new建立的例項都存放在堆記憶體中。
方法區:靜態成員、建構函式、常量池、執行緒池
本地方法區:window系統佔用
暫存器:

二、面向物件
1、面向物件思想:
(1)概述:面向物件是相對於面向過程而言的,面向過程強調的是功能,面向物件強調的是將功能封裝進物件,
強調具備功能的物件;
(2)思想特點:
A:是符合人們思考習慣的一種思想;
B:將複雜的事情簡單化了;
C:將程式設計師從執行者變成了指揮者;

比如我要達到某種結果,我就尋找能幫我達到該結果的功能的物件,如我要洗衣服我就買洗衣機,
至於怎麼洗我不管。
(3)特徵:
封裝:隱藏物件的屬性和實現細節,僅對外提供公共訪問方式
繼承: 多個類中存在相同屬性和行為時,將這些內容抽取到單獨一個類中,那麼多個類無需再定義
這些屬性和行為,只要繼承那個類即可。
多型: 一個物件在程式不同執行時刻代表的多種狀態,父類或者介面的引用指向子類物件
2、類和物件:
類:對現實世界中某類事物的描述,是抽象的,概念上的定義。
物件:事物具體存在的個體。

3:成員變數和區域性變數的區別(重點)
(1)作用域
成員變數:針對整個類有效。
區域性變數:只在某個範圍內有效。(一般指的就是方法,語句體內)
(2)儲存位置
成員變數:隨著物件的建立而存在,隨著物件的消失而消失,儲存在堆記憶體中。
區域性變數:在方法被呼叫,或者語句被執行的時候存在,儲存在棧記憶體中。
當方法呼叫完,或者語句結束後,就自動釋放。
(3)初始值
成員變數:有預設初始值。
區域性變數:沒有預設初始值,使用前必須賦值。

4、匿名物件
(1)匿名物件就是沒有名字的物件。是物件的一種簡寫形式。
(2)應用場景
A:只調用一次類中的方法。
B:可以作為實際引數在方法傳遞中使用

5、封裝:
指隱藏物件的屬性和實現細節,僅對外提供公共訪問方式;比如電腦機箱、筆記本等
好處:
將變化隔離;
方便使用;
提高複用性;
提高安全性

6、關鍵字private:封裝在程式碼中的體現
(1)私有的意思,許可權修飾符
(2)用來修飾成員變數和成員函式
(3)用private修飾的成員只在本類中有效
(4)私有是封裝的一種體現

7、構造方法:
(1)特點:
方法名與類名相同
沒有返回型別
沒有返回值
(2)作用:建構函式是用於建立物件,並對其進行初始化賦值,物件一建立就自動呼叫相對應的建構函式,
(3)構造方法的注意事項:
A:如果一個自定義類沒有構造方法,系統會預設給出一個無參構造方法。
B:如果一個自定義類提供了構造方法,那麼,系統將不再給出無參構造方法。
這個時候,你可以不使用無參構造方法。
如果你想使用,那麼,就必須手動給出無參構造方法。

建議:一般情況下,我們的自定義類都要手動給出無參構造方法。
(4)構造方法和成員方法的區別
A:格式區別
構造方法和類名相同,並且沒有返回型別,也沒有返回值。
普通成員方法可以任意起名,必須有返回型別,可以沒有返回值。
B:作用區別
構造方法用於建立物件,並進行初始化值。
普通成員方法是用於完成特定功能的。
C:呼叫區別
構造方法是在建立物件時被呼叫的,一個物件建立,只調用一次相應建構函式
普通成員方法是由建立好的物件呼叫,可以呼叫多次

8、構造程式碼塊:
(1)作用:給物件進行初始化,物件一建立就執行,而且優先於建構函式執行
(2)構造程式碼塊和建構函式的區別:
構造程式碼塊是給所有不同物件的共性進行統一初始化
建構函式是給對應的物件進行初始化

9、this關鍵字
(1)this關鍵字代表本類物件的一個引用,誰呼叫this所在的方法,this就代表誰
(2)this的使用場景
A:用於區分同名成員變數和區域性變數;
B:在定義函式時,該函式內部要用到呼叫該函式的物件時,因為此時物件還沒建立,故this代表此物件
B:建構函式間呼叫
**這個時候,this(引數)必須作為第一條語句存在。

10、Person p = new Person();在記憶體中做了哪些事情。
(1)將Person.class檔案載入進記憶體中。
(2)如果p定義在主方法中,那麼,就會在棧空間開闢一個變數空間p。
(3)在堆記憶體給物件分配空間。
(4)對物件中的成員進行預設初始化。
(5)對物件中的成員進行顯示初始化。
(6)呼叫構造程式碼塊對物件進行初始化。(如果沒有就不執行)
(7)呼叫構造方法對物件進行初始化。物件初始化完畢。
(8)將物件的記憶體地址賦值給p變數,讓p變數指向該物件。

11、static關鍵字:
(1)靜態的意思,用來修飾成員變數和成員函式
(2)靜態的特點:
隨著類的載入而載入
優先於物件存在
對所有物件共享
可以被類名直接呼叫
(3)靜態的注意事項
A:靜態方法只能訪問靜態成員
為什麼:因為靜態的內容是隨著類的載入而載入,它是先進記憶體的。
B:靜態方法中不能使用this,super關鍵字
C:主方法是靜態的
public static void main(String[] args)
public:公共的意思,是最大許可權修飾符。
static:由於jvm呼叫main方法的時候,沒有建立物件。
只能通過類名呼叫。所以,main必須用static修飾。
void:由於main方法是被jvm呼叫,不需要返回值。用void修飾。
main:main是主要的意思,所以jvm採用了這個名字。是程式的入口。

String[]:字串陣列
args:陣列名

在執行的時候,通過java命令給args陣列賦值。
格式:java MainTest hello world itcast
(4)靜態變數和成員變數的區別
A:呼叫方式
靜態變數也稱為類變數,可以直接通過類名呼叫。也可以通過物件名呼叫。
這個變數屬於類。
成員變數也稱為例項變數,只能通過物件名呼叫。這個變數屬於物件。
B:儲存位置
靜態變數儲存在方法區長中的靜態區。
成員變數儲存在堆記憶體。
C:生命週期
靜態變數隨著類的載入而存在,隨著類的消失而消失。生命週期長。
成員變數隨著物件的建立而存在,隨著物件的消失而消失。
D:與物件的相關性
靜態變數是所有物件共享的資料。
成員變數是每個物件所特有的資料。
(5)靜態的優點和弊端
優點:
對物件的共享資料進行單獨空間的儲存,節省記憶體,沒有必要每個物件都儲存一份
可直接被類名呼叫
弊端:
生命週期過長,隨著類的消失而消失
訪問出現許可權,即靜態雖好但只能訪問靜態
(6)什麼使用使用靜態呢?
A:當所有物件共享某個資料的時候,就把這個成員變數定義為靜態修飾的。
B:當某個方法沒有訪問該類中的非靜態成員,就可以把這個方法定義為靜態修飾。

靜態的生命週期比較長,所以一般不推薦使用。
(7)靜態程式碼塊
A:它只執行一次,它比main還先執行。
B:執行順序
靜態程式碼塊--構造程式碼塊--構造方法

12、製作API(次重點)
API(全拼):Application Program Interface 應用程式程式設計介面。
(1)類中的內容需要用文件註釋。
(2)使用JDK\bin目錄下的javadoc工具。
格式:javadoc -d 目錄 -author -version ArrayTool.java

13、單例設計模式:
(1)設計模式:
解決某類問題行之有效的方法,是一種思想,是規律的總結
(2)用來保證某個類在記憶體中只有一個物件
(3)保證唯一性的思想及步驟
為了避免其他程式建立該類物件,先禁止其他程式建立該類物件,即將建構函式私有化

為了其他程式訪問到該類物件,須在本類中建立一個該類私有物件
**為了方便其他程式訪問到該類物件,可對外提供一個公共訪問方式

比如API中的Runtime類就是單例設計模式。

(4)單例設計模式的兩種方式
A:餓漢式 當類載入的時候,就建立物件。

class Student
{
private Student(){}

private static final Student s = new Student();

public static Student getInstance()
{
return s;
}
}

B:懶漢式 當使用的使用,才去建立物件。

class Student
{
private Student(){}

private static final Student s = null;

public static Student getInstance()
{
if(s==null) 
{
//執行緒1就進來了,執行緒2就進來了。
s = new Student();
}
return s;
}
}

漢式和懶漢式的區別:
**
餓漢式是類一載入進記憶體就建立好了物件;
懶漢式則是類才載入進記憶體的時候,物件還沒有存在,只有呼叫了getInstance()方法時,
物件才開始建立。
**
懶漢式是延遲載入,如果多個執行緒同時操作懶漢式時就有可能出現執行緒安全問題,解決執行緒安全問題
可以加同步來解決。但是加了同步之後,每一次都要比較鎖,效率就變慢了,
所以可以加雙重判斷來提高程式效率。
注:開發常用餓漢式,因為餓漢式簡單安全。懶漢式多執行緒的時候容易發生問題

14、Math類的使用(重點)
(1)數學操作類:該類沒有建構函式,方法均為靜態的
(2)掌握內容
A:成員變數
E:比任何其他值都更接近e(即自然對數的底數)的double值。

PI:比任何其他值都更接近pi(即圓的周長與直徑之比)的double值。
B:成員方法
static double abs(double a)
返回 double 值的絕對值。返回絕對值

static double ceil(double a)
返回最小的(最接近負無窮大)double 值,該值大於等於引數,並等於某個整數。
static double floor(double a)
返回最大的(最接近正無窮大)double 值,該值小於等於引數,並等於某個整數。

max:返回兩個值中較大的那個
min:返回兩個值中較小的那個

static long round(double a) 返回最接近引數的 long。
static int round(float a) 返回最接近引數的 int。
static double random()
返回帶正號的 double 值,該值大於等於 0.0 且小於 1.0。

static double pow(double a, double b)
返回第一個引數的第二個引數次冪的值。
static double sqrt(double a)
返回正確舍入的 double 值的正平方根。
15、Random類的使用(重點)
(1)產生隨機數的類
(2)掌握內容
A:構造方法

Random() 建立一個新的隨機數生成器。
Random(long seed) 使用單個 long 種子建立一個新的隨機數生成器。
B:成員方法

int nextInt() 返回下一個偽隨機數,它是此隨機數生成器的序列中均勻分佈的 int 值。
int nextInt(int n) 返回一個偽隨機數,它是取自此隨機數生成器序列的、
在 0(包括)和指定值(不包括)之間均勻分佈的 int 值。
16、Scanner類的使用
(1)可以獲取從鍵盤的輸入資料
(2)掌握內容
構造方法:
Scanner(InputStream source) 構造一個新的 Scanner,它生成的值是從指定的輸入流掃描的。
如:Scanner sc = new Scanner(System.in);
方法摘要
sc.nextInt();獲取整型資料
sc.nextLine();獲取字串資料
17、繼承(重點)
(1)把很多類的相同特徵和行為進行抽取,用一個類來描述。讓多個類和這個類產生一個關係。
這樣的話,多個類就可以省略很多程式碼。這個關係就是繼承。java中用extends關鍵字表示。
(2)繼承的體系結構
A:多個具體的物件,不斷的向上抽取共享的內容,最終形成了一個體系。這個體系叫做繼承體系。
B:繼承體系的學習和使用原則

學習頂層的內容。因為他是整個體系的共性內容。
**建立子類使用。也就是使用底層的具體物件。
(3)繼承的特點:
A:java中只能單繼承,沒有多繼承。
B:java可以有多重(層)繼承。
(4)繼承的好處:
繼承的出現提高了程式碼的複用性。
繼承的出現讓類與類之間產生了關係,提供了多型的前提。
(5)子父類中的成員關係
A:成員變數
在子類方法中使用一個變數時:
首先,在方法的區域性變數中找這個變數,有則使用。
否則,在本類中找成員變數,有則使用。
否則,在父類中找成員變數,有則使用。
否則,報錯。
B:成員方法
用子類物件使用一個方法時。
首先,在子類中找這個方法,有則使用。
否則,在父類中找這個方法,有則使用。
否則,報錯。

重寫和過載的區別?
過載:在同一類中。方法名相同,引數列表不同。過載可以改變返回型別。
重寫:在不同類中(子父類中)。
方法宣告相同(返回型別,方法名,引數列表均相同)。
重寫需要注意:
子類方法的訪問許可權要大於等於父類方法的訪問許可權。

靜態只能重寫靜態。但是這種情況一般不會出現。

構造方法
子類的例項化過程
*子類建立物件時,會先去建立父類的物件。
預設是去呼叫父類的無參構造方法。
*子類構造方法中,第一行預設是super()
*為什麼子類中第一行會預設有super()
因為他繼承父類的成員使用,使用前這些成員必須初始化,
而他們是父類的成員,所以,必須通過父類進行初始化。
所以,會先建立一個父類的物件。
當父類沒有無參構造方法時
必須使用this或者super呼叫其他的構造方法。
(6)this和super的區別
this:代表本類物件的引用。
super:代表父類的儲存空間。
18、final關鍵字(重點)
(1)最終的意思,可以用於修飾類,方法,變數。
(2)final修飾的類不能被繼承。
final修飾的方法不能被重寫。
final修飾的變數是一個常量。只能被賦值一次。
內部類只能訪問被final修飾的區域性變數。
19、抽象類(重點)
(1)多個類有相同的方法宣告,但是方法體不一樣。這個時候,我們考慮把方法宣告進行抽取。
讓子類繼承後,自己去實現方法體。沒有方法體的方法,我們需要用抽象標誌下。
抽象的關鍵字是:abstract。
(2)抽象類:
該方法稱為抽象方法,包含抽象方法的類就是抽象類。
(3)抽象類的特點:
A:抽象類和抽象方法都要用abstract進行修飾
B:抽象類不能被例項化
C:抽象類中不一定有抽象方法,但是,有抽象方法的類一定是抽象類。
(4)抽象類中資料的特點
A:成員變數
抽象類中可以有變數,也可以有常量。
B:成員方法
抽象類中可以有抽象方法,也可以有非抽象方法。
C:構造方法
抽象類是一個類,所以,它有構造方法。
雖然本身不能例項化。但是可以給子類例項化使用。
(5)抽象類中的問題
A:抽象類中是否有構造方法?能不能被例項化?如果不能,為什麼有構造方法?
抽象類有構造方法。
抽象類不能被例項化。
抽象類中的構造方法供子類例項化呼叫。
B:抽象關鍵字abstract不可以和哪些關鍵字共存?

private:
私有內容子類繼承不到,所以,不能重寫。
但是abstract修飾的方法,要求被重寫。兩者衝突。
final
final修飾的方法不能被重寫。
而abstract修飾的方法,要求被重寫。兩者衝突。

static
假如一個抽象方法能通過static修飾,那麼這個方法,就可以直接通過類名呼叫。
而抽象方法是沒有方法體的,這樣的呼叫無意義。所以,不能用static修飾。
C:抽象類中可不可以沒有抽象方法?如果可以,這樣的類有什麼用嗎?
抽象類可以沒有抽象方法。
抽象類中沒有抽象方法的作用,只是為了不讓別的類建立該抽象類物件。這個在awt中有體現。
20、介面interface
(1)當一個類中的方法都是抽象的時候,java提供了另一種表示方式,叫介面。
用interface關鍵字表示。類與介面關係用implements表示。
(2)介面的成員特點
A:成員變數
是常量,預設修飾 public static final
B:成員方法
都是抽象的,預設修飾 public abstract
(3)關係
A:類與類的關係
是繼承關係。類與類只能單繼承,可以多重繼承。
B:類和介面的關係
是實現關係。類可以多實現介面。
類在繼承一個類的同時,可以實現多個介面。
C:介面和介面的關係
是繼承關係。介面可以多繼承介面。
(4)介面的特點
A:是對外暴露的規則
B:是功能的擴充套件
C:介面的出現降低耦合性。
耦合(類與類之間的關係)
內聚(類完成功能的能力)
程式設計規範:低耦合,高內聚。
D:介面可以多實現。如:CPU和主機板、筆記本的USB插口、插座
(5)介面和抽象類的區別
A:抽象類只能被單繼承
介面可以多實現,介面的出現避免了多繼承的侷限性。
B:抽象類中的資料特點:
成員變數:可以是變數,也可以是常量
成員方法:可以是抽象方法,也可以是非抽象方法
構造方法:有構造方法
介面中的資料特點:
成員變數:是常量。預設修飾 public static final
成員方法:都是抽象方法。都有預設修飾 public abstract
構造方法:沒有構造方法
C:抽象類中定義的是繼承體系中的共性功能。
介面中定義的是繼承體系中的擴充套件功能。
D:抽象類被繼承是"is a"關係:xx是yy的一種
介面被實現是"like a"關係:xx像yy的一種
21、多型:
(1)同一個物件,在程式不同時刻的多種執行狀態。舉例:動物,狗是狗,狗是動物。水(氣態,液態,固態)
(2)多型前提
A:存在著繼承或者實現關係
B:有方法的重寫
C:父類(介面)引用指向子類(實現)物件
(3)多型的好處和弊端:
好處:多型的存在提高了程式的擴充套件性和後期可維護性
弊端:雖然可以預先使用,但是隻能訪問父類中已有的功能,執行的是後期子類的功能內容。
不能預先使用子類中定義的特有功能。
(4)多型中物件呼叫成員的特點
Fu f = new Zi();

A:成員變數
編譯看左邊,執行看左邊
B:成員方法
編譯看左邊,執行看右邊
C:靜態方法
編譯看左邊,執行看左邊
(5)多型的思想
指揮同一批物件做事情。舉例:帶兵打仗,下課等。
22、instanceof關鍵字
A:用於判斷某個物件是否是某種型別。
B:格式
物件名 instanceof 子類(實現)名
23、Object類:
(1)是所有類的根類,超類。
java中提供的類以及我們自定義的類都直接或者間接的繼承自Object類。
(2)Object類中的方法
A:void finalize()
當垃圾回收器確定不存在對該物件的更多引用時,由物件的垃圾回收器呼叫此方法。
B:Class getClass()
獲取物件的位元組碼檔案的描述類,後面再講反射的時候還會在說這個類。
String name = s.getClass().getName();
C:int hashCode()
獲取物件的雜湊值。其實就是物件的記憶體地址值十進位制表示
D:String toString()
返回物件的字串表示。
表示格式:
getClass().getName()+"@"+Integer.toHexString(hashCode());

一般我們輸出物件名的時候,其實底層呼叫的就是該物件的toString()方法。
這種返回沒有意義,所以,我們會重寫這個方法,顯示類的成員變數資訊。
E:boolean equals(Object obj)
用於比較兩個物件的地址值是否相同。
我們獲取物件後,比較它的地址值意義不大。所以也會對這個方法進行重寫。
重寫要完成什麼功能,是根據需求定的。
(3)和equals的用法:
A:
怎麼用?
可以用於比較基本資料型別,比較的就是基本資料型別的值是否相等。

可以用於比較引用資料型別,比較的是物件的地址值是否相等。
B:equals怎麼用?
equals只能用於比較引用資料型別的。
Object提供的equals是用於比較物件地址值是否相同。

自定義類中,如果重寫了equals方法,那麼就是按照你自己的需求來比較的。

24、package關鍵字
(1)包:其實就是資料夾。用於區分不同包下相同的類名。
(2)好處:
A:對類檔案進行分類管理。
B:給類提供了多層名稱空間
aaa.Demo
bbb.Demo
C:寫在程式檔案的第一行。
D:包也是一種封裝形式。
25、import關鍵字
(1)匯入包的關鍵字
(2)格式:
import 包名;
(3)注意:
A:一個程式檔案中只有一個package,可以有多個import。
B:用來導包中的類,不匯入包中的包。
C:通常寫import mypack.Demo,明確自己使用的類。
(4)關鍵字的順序
類,包,導包這些關鍵的順序。
包 -- > 到包 -- > 類
26、不同修飾符可以修飾哪些內容
本類中 同一個包中 不同包中的子類中 不同包中
private OK
預設 OK Ok
protected OK Ok OK
public OK Ok OK Ok

類 構造方法 成員變數 成員方法
private OK OK OK
預設 Ok Ok Ok OK
protected OK OK Ok
public Ok Ok OK OK
static OK Ok
final Ok OK OK
abstract Ok OK

一般格式:
成員變數:
許可權修飾符+static/final+資料型別+成員變數名
public static final int NUM = 10;

成員方法:
許可權修飾符+static/final/abstract+返回型別+方法名
27、內部類(次重點)
(1)把一個類定義在某個類中的,這個類就被稱為內部類,內建類,巢狀類。
(2)訪問特點:
A:內部類可以直接訪問外部類中的成員,因為內部類持有外部類的引用,
格式為:外部類名.this
B:外部類要想訪問內部類的成員,必須建立物件訪問。
(3)內部類的訪問格式:
A:當內部類定義在外部類的成員位置,而且非私有,則可以在其他外部類中直接建立內部類物件
格式:外部類名.內部類名 變數名 = new 外部類物件.內部類物件
如:Outer.Inner in = new Outer().new Inner()
B:當內部類在外部類成員位置,且被static修飾時
外部其他類可直接訪問靜態內部類的非靜態成員
格式:new 外部類名.內部類名().內部類成員
如:new Outer.Inner().function();

外部其他類可直接訪問靜態內部類的靜態成員
格式:new 外部類名.內部類名.內部類成員
如:new Outer.Inner.function();
(4)什麼使用時候內部類呢?
假如有A類和B類,A類想直接訪問B類的成員,B類訪問A類成員的時候,
需要建立A類物件進行訪問,這個時候,就可以把A類定義為B類的內部類。
(5)內部類的位置
A:成員位置
可以被private修飾(Body,Heart)

可以被static修飾。(它訪問的外部類的成員必須是靜態的)
B:區域性位置
**可以直接訪問外部類中的成員,因為還持有外部類的持用
也可以直接訪問區域性成員,但是區域性成員要用final修飾。
注意:區域性內部類不能用private和static修飾
(6)通過class檔案我們就可以區分是否帶有內部類,以及內部類的位置
Outer$Inner:成員內部類
Outer$1Inner:區域性內部類
28、匿名內部類(區域性內部類的簡寫) (重點)
(1)前提:繼承一個類或者實現一個介面
(注意不要弄混匿名內部類的前提和多型的前提)
(2)格式:
new 父類名或者介面名()
{
重寫父類方法或者實現介面中的方法。
也可以自定義其他方法。
};
(3)什麼時候定義匿名內部類?
匿名內部類只是為了簡化書寫,匿名內部類有侷限,通常定義匿名內部類時,該類方法不超過3個
(4)匿名內部類的好處和弊端:
好處:簡化程式碼書寫
弊端:
不能直接呼叫自己的特有方法
不能執行強轉換動作
如果該類裡面方法較多,不允許使用匿名內部類
29、模板設計模式:
在定義功能時,功能的一部分是確定的,有一部分是不確定的,而且確定的部分在使用不確定的部分,
可將不確定的部分暴露出去,由該類的子類去完成。
如:求一段程式的執行時間例子。
30、異常
(1)程式執行過程中的不正常現象就叫異常。
(2)導致程式執行不正常的現象有很多,所以,就有很多的異常物件。
而這些異常物件存在著共性的內容,所以,可以不斷的進行抽取。最終形成了異常的體系結構。
異常體系的根類是:Throwable
Throwable:
|--Error:重大的問題,我們處理不了。也不需要編寫程式碼處理。比如說記憶體溢位。
|--Exception:一般性的錯誤,是需要我們編寫程式碼進行處理的。
|--RuntimeException:執行時異常,這個我們也不需要處理。
其實就是為了讓他在執行時出問題,然後我們回來修改程式碼。
(3)異常的分類
異常有兩種:
編譯時被檢測異常:
該異常在編譯時,如果沒有處理(沒有拋也沒有try),編譯失敗。
該異常被標識,代表這可以被處理。
執行時異常(編譯時不檢測)
在編譯時,不需要處理,編譯器不檢查。
該異常的發生,建議不處理,讓程式停止。需要對程式碼進行修正。
(4)異常體系的特點:
異常體系中的所有類及其子類物件都具備可拋性。也就是說可以被throw和throws關鍵字所操作。
(5)main方法是如何處理異常的。
A:在main裡面編寫程式碼進行處理
B:交給jvm自己進行處理。採用的是jvm的預設處理方式。
其實就是相當於呼叫了異常物件的printStackTrace()方法。
(6)Throwable類的學習
getMessage():獲取異常資訊,返回字串。
toString():獲取異常類名和異常資訊,返回字串。
printStackTrace():獲取異常類名和異常資訊,以及異常出現在程式中的位置。返回值void。
(7)異常的處理·
A:try...catch...finally
基本格式:

try
{
可能出現異常的程式碼
}
catch(異常物件)
{    
異常處理程式碼
}
finally
{
釋放資源
}

變形格式:
try...catch
try...catch...catch...
try...catch...catch...finally
多個異常同時被捕獲的時候,記住一個原則:
先逮小的,再逮大的。

finally:永遠被執行,除非退出jvm。System.exit(0);
面試題2個。
***:final,finally,finalize區別。
final是最終的意思。它可以用於修飾類,成員變數,成員方法。
它修飾的類不能被繼承,它修飾的變數時常量,它修飾的方法不能被重寫。

finally:是異常處理裡面的關鍵字。
它其中的程式碼永遠被執行。特殊情況:在執行它之前jvm退出。System.exit(0);

finalize:是Object類中的一個方法。
它是於垃圾回收器呼叫的方式。

***:假如catch中有return語句, finally裡中的程式碼會執行嗎?
是在return前,還是在return後呢?
會,在return前執行finally裡面的程式碼。
(8)Exception和RuntimeException的區別
A:Exception:一般性的錯誤,是需要我們編寫程式碼進行處理的。
B:RuntimeException:執行時異常,這個我們也不需要處理。
其實就是為了讓他在執行時出問題,然後我們回來修改程式碼。
在用throws丟擲一個的時候,如果這個異常是屬於RuntimeException的體系的時候,
我們在呼叫的地方可以不用處理。(RuntimeException和RuntimeException的子類)

在用throws丟擲一個的時候,如果這個異常是屬於Exception的體系的時候,
我們在呼叫的地方必須進行處理或者繼續丟擲。
(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的區別
A:有throws的時候可以沒有throw。
有throw的時候,如果throw拋的異常是Exception體系,那麼必須有throws在方法上宣告。
B:throws用於方法的宣告上,其後跟的是異常類名,後面可以跟多個異常類,之間用逗號隔開
throw用於方法體中,其後跟的是一個異常物件名

三、多執行緒:
1、程序和執行緒:
程序:正在進行的程式。每一個程序執行都有一個執行順序,該順序是一個執行路徑,或者叫一個控制單元。
執行緒:程序內部的一條執行路徑或者一個控制單元。
兩者的區別:
一個程序至少有一個執行緒
程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體;
2、jvm多執行緒的啟動是多執行緒嗎?
java的虛擬機器jvm啟動的是單執行緒,就有發生記憶體洩露的可能,而我們使用java程式沒出現這樣的問題,
也就是jvm啟動至少有兩個執行緒,一個執行java程式,一個執行垃圾回收。所以是多執行緒。
2、多執行緒的優勢:
解決了多部分同時執行的問題,提高效率
3、執行緒的弊端:
執行緒太多會導致效率的降低,因為執行緒的執行依靠的是CPU的來回切換。
4、什麼叫多執行緒:
一個程序中有多個執行緒,稱為多執行緒。
5、實現多執行緒的方法:
實現多執行緒可以通過繼承Thread類和實現Runnable介面。
(1)繼承Thread
定義一個類繼承Thread類
複寫Thread類中的public void run()方法,將執行緒的任務程式碼封裝到run方法中
直接建立Thread的子類物件,建立執行緒
呼叫start()方法,開啟執行緒(呼叫執行緒的任務run方法)
//另外可以通過Thread的getName()獲取執行緒的名稱。

(2)實現Runnable介面;
定義一個類,實現Runnable介面;
覆蓋介面的public void run()的方法,將執行緒的任務程式碼封裝到run方法中;
建立Runnable介面的子類物件
將Runnabl介面的子類物件作為引數傳遞給Thread類的建構函式,建立Thread類物件
(原因:執行緒的任務都封裝在Runnable介面子類物件的run方法中。
所以要線上程物件建立時就必須明確要執行的任務)。
呼叫start()方法,啟動執行緒。

兩種方法區別:
(1)實現Runnable介面避免了單繼承的侷限性
(2)繼承Thread類執行緒程式碼存放在Thread子類的run方法中
實現Runnable介面執行緒程式碼存放在介面的子類的run方法中;
在定義執行緒時,建議使用實現Runnable介面,因為幾乎所有多執行緒都可以使用這種方式實現
6、建立執行緒是為什麼要複寫run方法?
Thread類用於描述執行緒。Thread類定義了一個功能,用於儲存執行緒要執行的程式碼,該儲存功能就是run方法。
7、start()和run方法有什麼區別?
呼叫start方法方可啟動執行緒,而run方法只是thread的一個普通方法,呼叫run方法不能實現多執行緒;
Start()方法:
start方法用來啟動執行緒,實現了多執行緒執行,這時無需等待run方法體程式碼執行完畢而直接繼續執行下面的
程式碼。通過呼叫Thread類的start()方法來啟動一個執行緒,這時此執行緒處於就緒(可執行)狀態,並沒有執行,
一旦得到cpu時間片(執行權),就開始執行run()方法,這裡方法run()稱為執行緒體,
它包含了要執行的這個執行緒的內容,Run方法執行結束,此執行緒隨即終止。
Run()方法:
run()方法只是Thread類的一個普通方法,如果直接呼叫Run方法,程式中依然只有主執行緒這一個執行緒,
其程式執行路徑還是隻有一條,還是要等待run方法體執行完畢後才可繼續執行下面的程式碼,
這樣就沒有達到多執行緒的目的。
8、執行緒的幾種狀態:
新建:new一個Thread物件或者其子類物件就是建立一個執行緒,當一個執行緒物件被建立,但是沒有開啟,這個時候,
只是物件執行緒物件開闢了記憶體空間和初始化資料。
就緒:新建的物件呼叫start方法,就開啟了執行緒,執行緒就到了就緒狀態。
在這個狀態的執行緒物件,具有執行資格,沒有執行權。
執行:當執行緒物件獲取到了CPU的資源。
在這個狀態的執行緒物件,既有執行資格,也有執行權。
凍結:執行過程中的執行緒由於某些原因(比如wait,sleep),釋放了執行資格和執行權。
當然,他們可以回到執行狀態。只不過,不是直接回到。
而是先回到就緒狀態。
死亡:當執行緒物件呼叫的run方法結束,或者直接呼叫stop方法,就讓執行緒物件死亡,在記憶體中變成了垃圾。
9、sleep()和wait()的區別:
(1)這兩個方法來自不同的類,sleep()來自Thread類,和wait()來自Object類。
(2)sleep是Thread的靜態類方法,誰呼叫的誰去睡覺,即使在a執行緒裡呼叫了b的sleep方法,實際上還是a去睡覺,
要讓b執行緒睡覺要在b的程式碼中呼叫sleep。而wait()是Object類的非靜態方法
(3)sleep()釋放資源不釋放鎖,而wait()釋放資源釋放鎖;
(4)使用範圍:wait,notify和notifyAll只能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用
10、多執行緒安全問題:
(1)原因:當程式的多條語句在操作執行緒共享資料時(如買票例子中的票就是共享資源),由於執行緒的隨機性導致
一個執行緒對多條語句,執行了一部分還沒執行完,另一個執行緒搶奪到cpu執行權參與進來執行,
此時就導致共享資料發生錯誤。比如買票例子中列印重票和錯票的情況。
(2)解決方法:對多條操作共享資料的語句進行同步,一個執行緒在執行過程中其他執行緒不可以參與進來
11、Java中多執行緒同步是什麼?
同步是用來解決多執行緒的安全問題的,在多執行緒中,同步能控制對共享資料的訪問。如果沒有同步,當一個執行緒在
修改一個共享資料時,而另外一個執行緒正在使用或者更新同一個共享資料,這樣容易導致程式出現錯誤的結果。
12、什麼是鎖?鎖的作用是什麼?
鎖就是物件
鎖的作用是保證執行緒同步,解決執行緒安全問題。
持有鎖的執行緒可以在同步中執行,沒有鎖的執行緒即使獲得cpu執行權,也進不去。
13、同步的前提:
(1)必須保證有兩個以上執行緒
(2)必須是多個執行緒使用同一個鎖,即多條語句在操作執行緒共享資料
(3)必須保證同步中只有一個執行緒在執行
14、同步的好處和弊端
好處:同步解決了多執行緒的安全問題
弊端:多執行緒都需要判斷鎖,比較消耗資源
15、同步的兩種表現形式:
(1)同步程式碼塊:
可以指定需要獲取哪個物件的同步鎖,使用synchronized的程式碼塊同樣需要鎖,但他的鎖可以是任意物件
考慮到安全問題,一般還是使用同一個物件,相對來說效率較高。

注意:
雖然同步程式碼快的鎖可以使任何物件,但是在進行多執行緒通訊使用同步程式碼快時,
必須保證同步程式碼快的鎖的物件和,否則會報錯。

同步函式的鎖是this,也要保證同步函式的鎖的物件和呼叫wait、notify和notifyAll的物件是
同一個物件,也就是都是this鎖代表的物件。
格式:
synchronized(物件)
{
需同步的程式碼;
}
(2)同步函式
同步方法是指進入該方法時需要獲取this物件的同步鎖,在方法上使用synchronized關鍵字,
使用this物件作為鎖,也就是使用了當前物件,因為鎖住了方法,所以相對於程式碼塊來說效率相對較低。
注:靜態同步函式的鎖是該方法所在的類的位元組碼檔案物件,即類名.class檔案
格式:
修飾詞 synchronized 返回值型別 函式名(引數列表)
{
需同步的程式碼;
}

在jdk1.5後,用lock鎖取代了synchronized,個人理解也就是對同步程式碼塊做了修改,
並沒有提供對同步方法的修改,主要還是效率問題吧。
16、多執行緒的單例設計模式:保證某個類中記憶體中只有一個物件
(1)餓漢式:

1 class Single
 2 {
 3 private Single(){}//將建構函式私有化,不讓別的類建立該類物件
 4 private static final Single s=new Single();//自己建立一個物件
 5 public static Single getInstance()//提供一個公共訪問方式
 6 {
 7 return s;
 8 }
 9 }
10 (2)懶漢式:
11 class Single
12 {
13 private Single(){} 
14 private static Single s;
15 public static Single getInstance()
16 {
17 if(s==null)
18 s=new Single();
19 return s;
20 }
21 }

餓漢式和懶漢式的區別:
**
餓漢式是類一載入進記憶體就建立好了物件;
懶漢式則是類載入進記憶體的時候,物件還沒有存在,只有呼叫了getInstance()方法時,物件才開始建立。
**
懶漢式是延遲載入,如果多個執行緒同時操作懶漢式時就有可能出現執行緒安全問題,解決執行緒安全問題
可以加同步來解決。但是加了同步之後,每一次都要比較鎖,效率就變慢了,
所以可以加雙重判斷來提高程式效率。
如將上述懶漢式的Instance函式改成同步:
public static Single getInstance()
{
if(snull)
{
synchronized(Single.class)
{
if(s
null)
s=new Single();
}
}
return s;
}
17、死鎖
兩個執行緒對兩個同步物件具有迴圈依賴時,就會發生死鎖。即同步巢狀同步,而鎖卻不同。
18、wait()、sleep()、notify()、notifyAll()
wait():使一個執行緒處於等待狀態,並且釋放所持有的物件的lock。
sleep():使一個正在執行的執行緒處於睡眠狀態,是一個靜態方法,呼叫此方法要捕捉InterruptedException異常。
notify():喚醒一個處於等待狀態的執行緒,注意的是在呼叫此方法的時候,並不能確切的喚醒某一個等待狀態的執行緒,
而是由JVM確定喚醒哪個執行緒(一般是最先開始等待的執行緒),而且不是按優先順序。
Allnotity():喚醒所有處入等待狀態的執行緒,注意並不是給所有喚醒執行緒一個物件的鎖,而是讓它們競爭。
18、為什麼wait()、notify()、notifyAll()這些用來操作執行緒的方法定義在Object類中?
(1)這些方法只存在於同步中;
(2)使用這些方法時必須要指定所屬的鎖,即被哪個鎖呼叫這些方法;
(3)而鎖可以是任意物件,所以任意物件呼叫的方法就定義在Object中。
19、多執行緒間通訊:
多執行緒間通訊就是多個執行緒在操作同一資源,但是操作的動作不同.
(1)為什麼要通訊
多執行緒併發執行的時候, 如果需要指定執行緒等待或者喚醒指定執行緒, 那麼就需要通訊.比如生產者消費者的問題,
生產一個消費一個,生產的時候需要負責消費的程序等待,生產一個後完成後需要喚醒負責消費的執行緒,
同時讓自己處於等待,消費的時候負責消費的執行緒被喚醒,消費完生產的產品後又將等待的生產執行緒喚醒,
然後使自己執行緒處於等待。這樣來回通訊,以達到生產一個消費一個的目的。
(2)怎麼通訊
在同步程式碼塊中, 使用鎖物件的wait()方法可以讓當前執行緒等待, 直到有其他執行緒喚醒為止.
使用鎖物件的notify()方法可以喚醒一個等待的執行緒,或者notifyAll喚醒所有等待的執行緒.
多執行緒間通訊用sleep很難實現,睡眠時間很難把握。

20、Lock和Condition
實現提供比synchronized方法和語句可獲得的更廣泛的鎖的操作,可支援多個相關的Condition物件
Lock是個介面
鎖是控制多個執行緒對共享資料進行訪問的工具。

JDK1.5中提供了多執行緒升級的解決方案:
將同步synchonized替換成了顯示的Lock操作,將Object中的wait、notify、notifyAll替換成了Condition物件。
該物件可以Lock鎖進行獲取

Lock的方法摘要:
void lock() 獲取鎖。
Condition newCondition() 返回繫結到此 Lock 例項的新 Condition 例項。
void unlock() 釋放鎖。
Condition方法摘要:
void await() 造成當前執行緒在接到訊號或被中斷之前一直處於等待狀態。
void signal() 喚醒一個等待執行緒。
void signalAll() 喚醒所有等待執行緒。

21、停止執行緒:
stop方法已經過時,如何停止執行緒?
停止執行緒的方法只有一種,就是run方法結束。如何讓run方法結束呢?
開啟多執行緒執行,執行程式碼通常是迴圈體,只要控制住迴圈,就可以讓run方法結束,也就是結束執行緒。

特殊情況:當執行緒屬於凍結狀態,就不會讀取迴圈控制標記,則執行緒就不會結束。
為解決該特殊情況,可引入Thread類中的Interrupt方法結束執行緒的凍結狀態;
當沒有指定的方式讓凍結執行緒恢復到執行狀態時,需要對凍結進行清除,強制讓執行緒恢復到執行狀態
22、interrupt:
void interrupt() 中斷執行緒:
中斷狀態將被清除,它還將收到一個 InterruptedException
22、守護執行緒(後臺執行緒)
setDaemon(boolean on):將該執行緒標記為守護執行緒或者使用者執行緒。
當主執行緒結束,守護執行緒自動結束,比如聖鬥士星矢裡面的守護雅典娜,
在多執行緒裡面主執行緒就是雅典娜,守護執行緒就是聖鬥士,主執行緒結束了,
守護執行緒則自動結束。
當正在執行的執行緒都是守護執行緒時,java虛擬機器jvm退出;所以該方法必須在啟動執行緒前呼叫;

守護執行緒的特點:
守護執行緒開啟後和前臺執行緒共同搶奪cpu的執行權,開啟、執行兩者都沒區別,
但結束時有區別,當所有前臺執行緒都結束後,守護執行緒會自動結束。
23、多執行緒join方法:
void join() 等待該執行緒終止。
void join(long millis) 等待該執行緒終止的時間最長為 millis 毫秒。
throws InterruptedException
特點:當A執行緒執行到B執行緒的join方法時,A就會等待B執行緒都執行完,A才會執行
作用: join可以用來臨時加入執行緒執行;
24、多執行緒優先順序:yield()方法
yield():暫停當前正在執行的執行緒物件,並執行其他執行緒
setPriority(int newPriority):更改執行緒優先順序
int getPriority() 返回執行緒的優先順序。
String toString() 返回該執行緒的字串表示形式,包括執行緒名稱、優先順序和執行緒組

(1)MAX_PRIORITY:最高優先順序(10級)
(1)Min_PRIORITY:最低優先順序(1級)
(1)Morm_PRIORITY:預設優先順序(5級)

25、什麼是ThreadLocal類,怎麼使用它?
ThreadLocal類提供了執行緒區域性 (thread-local) 變數。是一個執行緒級別的區域性變數,並非“本地執行緒”。
ThreadLocal 為每個使用該變數的執行緒,提供了一個獨立的變數副本,每個執行緒修改副本時不影響其它執行緒物件的副本

下面是執行緒區域性變數(ThreadLocal variables)的關鍵點:
一個執行緒區域性變數(ThreadLocal variables)為每個執行緒方便地提供了一個單獨的變數。
ThreadLocal 例項通常作為靜態的私有的(private static)欄位出現在一個類中,這個類用來關聯一個執行緒。
當多個執行緒訪問 ThreadLocal 例項時,每個執行緒維護 ThreadLocal 提供的獨立的變數副本。
常用的使用可在 DAO 模式中見到,當 DAO 類作為一個單例類時,
資料庫連結(connection)被每一個執行緒獨立的維護,互不影響。(基於執行緒的單例)
26、什麼時候丟擲InvalidMonitorStateException異常?為什麼?
呼叫 wait ()/notify ()/notifyAll ()中的任何一個方法時,如果當前執行緒沒有獲得該物件的鎖,
那麼就會丟擲 IllegalMonitorStateException 的異常
也就是說程式在沒有執行物件的任何同步塊或者同步方法時,
仍然嘗試呼叫 wait ()/notify ()/notifyAll ()時。由於該異常是 RuntimeExcpetion 的子類,
所以該異常不一定要捕獲(儘管你可以捕獲只要你願意
作為 RuntimeException,此類異常不會在 wait (),notify (),notifyAll ()的方法簽名提及。
27、在靜態方法上使用同步時會發生什麼事?
同步靜態方法時會獲取該類的“Class”物件,所以當一個執行緒進入同步的靜態方法中時,
執行緒監視器獲取類本身的物件鎖,其它執行緒不能進入這個類的任何靜態同步方法。
它不像例項方法,因為多個執行緒可以同時訪問不同例項同步例項方法。
28、當一個同步方法已經執行,執行緒能夠呼叫物件上的非同步例項方法嗎?
可以,一個非同步方法總是可以被呼叫而不會有任何問題。
實際上,Java 沒有為非同步方法做任何檢查,鎖物件僅僅在同步方法或者同步程式碼塊中檢查。
如果一個方法沒有宣告為同步,即使你在使用共享資料Java照樣會呼叫,而不會做檢查是否安全,
所以在這種情況下要特別小心。一個方法是否宣告為同步取決於臨界區訪問(critial section access),
如果方法不訪問臨界區(共享資源或者資料結構)就沒必要宣告為同步的。
29、在一個物件上兩個執行緒可以呼叫兩個不同的同步例項方法嗎?
不能,因為一個物件已經同步了例項方法,執行緒獲取了物件的物件鎖。
所以只有執行完該方法釋放物件鎖後才能執行其它同步方法。
30、什麼是執行緒餓死,什麼是活鎖?
執行緒餓死和活鎖雖然不像死鎖一樣是常見的問題,但是對於併發程式設計的設計者來說就像一次邂逅一樣。
當所有執行緒阻塞,或者由於需要的資源無效而不能處理,不存在非阻塞執行緒使資源可用。
JavaAPI 中執行緒活鎖可能發生在以下情形:
當所有執行緒在程式中執行 Object.wait (0),引數為 0 的 wait 方法。
程式將發生活鎖直到在相應的物件上有執行緒呼叫 Object.notify ()或者 Object.notifyAll ()。
當所有執行緒卡在無限迴圈中。

四、集合框架
1:String類:字串(重點)
(1)多個字元組成的一個序列,叫字串。
生活中很多資料的描述都採用的是字串的。而且我們還會對其進行操作。
所以,java就提供了這樣的一個類供我們使用。
(2)建立字串物件

1 A:String():無參構造
 2 **舉例:
 3 String s = new String();
 4 s = "hello";
 5 sop(s);
 6 B:String(byte[] bys):傳一個位元組陣列作為引數 *****
 7 **舉例
 8 byte[] bys = {97,98,99,100,101};
 9 String s = new String(bys);
10 sop(s);
11 C:String(byte[] bys,int index,int length):把位元組陣列的一部分轉換成一個字串 *****
12 **舉例
13 byte[] bys = {97,98,99,100,101};
14 String s = new String(bys,1,2);
15 sop(s);
16 D:String(char[] chs):傳一個字元陣列作為引數 *****
17 **舉例
18 char[] chs = {'a','b','c','d','e'};
19 String s = new String(chs);
20 sop(s);
21 E:String(char[] chs,int index,int length):把字元陣列的一部分轉換成一個字串 *****
22 **舉例
23 char[] chs = {'a','b','c','d','e'};
24 String s = new String(chs,1,2);
25 sop(s);    
26 F:String(String str):把一個字串傳遞過來作為引數
27 char[] chs = {'a','b','c','d','e'};
28 String ss = new String(s);
29 sop(ss);
30 G:直接把字串常量賦值給字串引用物件(最常用) *****
31 **舉例
32 String s = "hello";
33 sop(s);

(3)面試題
A:請問String s = new String("hello");建立了幾個物件。
兩個。一個"hello"字串物件,在方法區的常量池;一個s物件,在棧記憶體。

B:請寫出下面的結果
String s1 = new String("abc");
Strign s2 = new String("abc");
String s3 = "abc";
String s4 = "abc";

sop(s1s2); //false
sop(s1
s3); //false
sop(s3==s4); //true
C:字串物件一旦被建立就不能被改變。
指的是字串常量值不改變。
(4)字串中各種功能的方法
A:判斷
boolean equals(Object anObject):判斷兩個字串的內容是否相同,複寫了Object的方法
boolean equalsIgnoreCase(String anotherString):判斷兩個字串的內容是否相同,
不區分大小寫
boolean contains(String s):判斷一個字串中是否包含另一個字串
注意:判斷字串是否包含特殊字元.直接表示為str.contains(".")
boolean endsWith(String suffix):測試此字串是否以指定的字尾結束
boolean startsWith(String suffix):測試此字串是否以指定的字首開始
boolean isEmpty():測試字串是否為空
B:獲取

  • int length():返回此字串的長度
  • char charAt(int index):返回指定索引處的 char值
  • int indexOf(int ch):返回指定字元在此字串中第一次出現處的索引。
    int indexOf(int ch, int fromIndex):返回在此字串中第一次出現指定字元處的索引,
    從指定的索引開始搜尋。
    int indexOf(String str):返回指定子字串在此字串中第一次出現處的索引。
    int indexOf(String str, int fromIndex):返回指定子字串在此字串中第一次
    出現處的索引,從指定的索引開始。
  • int lastIndexOf(int ch):返回指定字元在此字串中最後一次出現處的索引。
    int lastIndexOf(int ch, int fromIndex)
    返回指定字元在此字串中最後一次出現處的索引,從指定的索引處開始進行反向搜尋。
    int lastIndexOf(String str)
    返回指定子字串在此字串中最右邊出現處的索引。
    int lastIndexOf(String str, int fromIndex)
    返回指定子字串在此字串中最後一次出現處的索引,從指定的索引開始反向搜尋。
    *** String substring(int beginIndex) (注意:該方法substring的String是小寫!!!)
    返回一個新的字串,它是此字串的一個子字串。
    String substring(int beginIndex, int endIndex) (注意該方法的String是小寫!!!)
    返回一個新字串,它是此字串的一個子字串,包含頭不包含尾。
    C:轉換
  • byte[] getBytes():(很常用!)從字串到位元組陣列的方法
    void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
    將字元從此字串複製到目標字元陣列。
  • char[] toCharArray():(很常用!)從字串到字元陣列的方法
    static String copyValueOf(char[] data)
    返回指定陣列中表示該字元序列的 String。
    static String copyValueOf(char[] data, int offset, int count)
    返回指定陣列中表示該字元序列的 String。
  • static String valueOf(資料型別):把該資料型別的資料轉換成字串。
  • String toLowerCase():把字串轉換成小寫
    String toUpperCase():把字串轉換成大寫
  • 字串的連線
    String concat(String str):將指定字串連線到此字串的結尾。
    D:替換
    String replace(char oldChar, char newChar):用新字元替換舊字元(替換所有)
    String replace(String target, String replacement):用新的子串換舊串
    E:分割
    String[] split(String regex):根據指定的字串把一個字串分割成一個字串陣列
    F:
    String trim():去除字串的前後空格
    G:
    int compareTo(String anotherString)
    按字典順序比較兩個字串。
    int compareToIgnoreCase(String str)
    按字典順序比較兩個字串,不考慮大小寫。
    (5)練習
    1:模擬登入,給三次機會,並提示還有幾次.
    預設的使用者名稱和密碼為admin。 區分大小寫。
    自己從鍵盤輸入使用者名稱和密碼。

2:給定一個字串統計,統計大寫字母,小寫字母,數字出現的個數.
***注意:不包括特殊字元
從鍵盤輸入一個不包含特殊字元的字串(只有26個字母和0-9組成)。

3:給定一個字串,把它變成首字母大寫,其他字母小寫的字串.
從鍵盤輸入一個字串,全部26個字母組成的。

4:子串在整串中出現的次數。
也就是說:獲取一個字串中,指定的字串在該字串中出現的次數.
例如:
"nbasdnbafllgnbahjnbakqqqqlnba" 在這個字串中,多有個nba.

5:對字串中字元進行自然順序排序。
"basckd"-->"abcdks"

先留做思考內容:
6:兩個字串的最大相同子串。
兩個字串的最大相同子串。
比如:
"sadabcdfghjkl"
werabcdtyu"

2:StringBuffer
(1)字串的緩衝區,是一個容器。
(2)它和String的區別
它是緩衝區可變長度的。
(3)構造方法
StringBuffer() 構造一個其中不帶字元的字串緩衝區,初始容量為 16 個字元。
StringBuffer(int num) 構造一個不帶字元,但具有指定初始容量的字串緩衝區。
StringBuffer(String str) 構造一個字串緩衝區,並將其內容初始化為指定的字串內容。
(4)常用方法
A:增加資料
append :新增各種型別的資料

insert : 在容器指定位置插入各種型別的資料。
B:刪除資料
deleteCharAt : 刪除指定位置的字元

delete 還可以用於清空StringBuffer的緩衝區
C:替換
replace
D:獲取

charAt
E:長度和容量
length() 元素的個數

capacity 元素的理論值
F:獲取元素的位置
indexOf

lastIndexOf
G:擷取
substring(int start)

substring(int start,int end)
H:反轉
**reverse
(5)字串和StringBuffer的轉換
String-->StringBuffer通過構造:
如:StringBuffer sb = new StringBuffer(String str)
StringBuffer--String通過toString方法
如:StringBuffer sb = new StringBuffer();
sb.toString();

3:StringBuilder
和StringBuffer的功能是一樣的,但是有區別:
StringBuffer(JDK1.0)是執行緒安全的。
StringBuilder(JDK1.5)不保證執行緒安全。

一般來說,我們寫的程式都是單執行緒的,所以,用StringBuilder,效率高。

JDK版本的升級原則:
A:提高效率
B:提高安全性
C:簡化書寫

4:基本資料型別的物件包裝類
(1)為了更方便的操作每個基本資料型別,java對其提供了很多的屬性和方法供我們使用。
(2)用途:
將基本資料型別封裝成物件的好處在於可以在物件中定義更多的功能操作該資料。

常用的操作之一:用於基本資料型別與字串之間的轉換。
A:方便操作
B:用於和字串進行相互轉換
(3)基本資料型別和物件型別的對應
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
(4)構造方法

欄位摘要:
static int MAX_VALUE 值為 2^31-1 的常量,它表示 int 型別能夠表示的最大值
static int MIN_VALUE 值為 -2^31 的常量,它表示 int 型別能夠表示的最小值
static Class TYPE 表示基本型別int的Class 例項

Integer(int value) 構造一個新分配的Integer物件,它表示指定的int值。
Inreger(String s) 注意:s必須是純數字的字串。否則會有異常NumberFormatException

(5)幾個常用的方法
Integer.toBinaryString();
以二進位制(基數 2)無符號整數形式返回一個整數引數的字串表示形式。
Integer.toOctalString();
以八進位制(基數 8)無符號整數形式返回一個整數引數的字串表示形式。
Integer.toHexString();
以十六進位制(基數 16)無符號整數形式返回一個整數引數的字串表示形式。
static int Integer.parseInt(String s) 將字串引數作為有符號的十進位制整數進行解析,
字串必須是int型範圍內的數字字串
static int Integer.parseInt(String s,int basic)
使用第二個引數指定的基數,將字串引數解析為有符號的整數.
字串必須是int型範圍內的數字字串
short shortValue() 以short型別返回該Integer的值。
int intValue() 以int型別返回該Integer的值。
static Integer valueOf(int num) 返回一個表示指定的 int 值的 Integer 例項。
static Integer valueOf(String s) 返回儲存指定的String的值的Integer物件。
static Integer valueOf(String s, int radix)
返回一個Integer物件,該物件中儲存了用第二個引數提供的基數進行
解析時從指定的String中提取的值。

(6)型別轉換

 1 int -- Integer
 2 int num = 20;
 3 A:Integer i = new Integer(num);
 4 B:Integer i = Integer.valueOf(num);
 5 Integer -- int
 6 Integer i = new Integer(20);
 7 A:int num = i.intValue();
 8 
 9 int -- String
10 int num = 20;
11 A:String s = String.valueOf(num);
12 B:String s = ""+num;
13 C:String s = Integer.toString(num);
14 String -- int
15 String s = "20";
16 A:int num = Integer.parseInt(s);
17 B:Integer i = new Integer(s);或者Integer i = Integer.valueOf(s);
18 int num = i.intValue();    

6、集合框架:
(1)為什麼出現集合類?
面向物件對事物的體現都是以物件的形式,為了方便對多個物件的操作,就對物件進行儲存。
集合就是儲存物件最常用的一種方式.
(2)陣列和集合都是容器,兩者有何不同?
陣列長度固定,而集合長度是可變的

陣列值可以儲存物件,還可以儲存基本資料型別;而集合只能儲存物件
陣列儲存資料型別是固定的,而集合儲存的資料型別不固定
(3)集合類的特點:
集合只能儲存物件
集合的長度是可變的
集合可以儲存不同型別的物件
(4)集合類框架(重要!!!要分清幾種容器間的區別):

Collection:頂層介面
|--->List:列表,元素是有序的(元素帶角標索引),可以有重複元素,可以有null元素。
|--->ArrayList(JDK1.2):底層的資料結構是陣列資料結構,特點是查詢速度快(因為帶角標),
但是增刪速度稍慢,因為當元素多時,增刪一個元素則所有元素的角標都得改變
執行緒不同步。預設長度是10,當超過長度時,按50%延長集合長度。
|--->LinkedList(JDK1.2):底層資料結構式連結串列資料結構(即後面一個元素記錄前一個),
特點:查詢速度慢,因為每個元素只知道前面一個元素,但增刪速度快
因為元素再多,增刪一個,只要讓其前後的元素重新相連即可
執行緒是不同步的。
|--->Vector(JDK1.0):底層資料結構是陣列資料結構.特點是查詢和增刪速度都很慢。
預設長度是10,當超過長度時,按100%延長集合長度。
執行緒同步。
(Vector功能跟ArrayList功能一模一樣,已被ArrayList替代)

**List使用注意!
|--->ArrayList:
(1)當往ArrayList裡面存入元素沒什麼要求時,即只要求有序就行時;

(2)當往ArrayList裡面存入元素要求不重複時,比如存入學生物件,當同名同姓時
視為同一個人,則不往裡面儲存。則定義學生物件時,需複寫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集合通過add存入學生物件時,集合底層自己會呼叫學生類的equals方法,
判斷重複學生則不存入。
注:對於List集合,無論是add、contains、還是remove方法,判斷元素是否相同,
都是通過複寫equals方法來判斷!

|--->LinkedList
(1)LinkLedist的特有方法:
boolean offerFirst(E e) 在此列表的開頭插入指定的元素。
boolean offerLast(E e) 在此列表末尾插入指定的元素。
E peekFirst() 獲取但不移除此列表的第一個元素;如果此列表為空,則返回 null。
E peekLast() 獲取但不移除此列表的最後一個元素;如果此列表為空,則返回 null。
E pollFirst() 獲取並移除此列表的第一個元素;如果此列表為空,則返回 null。
E pollLast() 獲取並移除此列表的最後一個元素;如果此列表為空,則返回 null。
(2)通過LinkLedist的特有方法,可以實現某些資料特殊方式的存取,比如堆疊和佇列。

一般情況下,使用哪種List介面下的實現類呢?
如果要求增刪快,考慮使用LinkedList
如果要求查詢快,考慮使用ArrayList
如果要求執行緒安全,考慮使用Vector。

|--->Set:集合,元素是無序的(因為沒有索引),元素不可以重複。可以有null元素。
|--->HashSet(JDK1.2):底層資料結構是雜湊表、存取速度快、元素唯一、執行緒不同步。
保證性元素唯一的原理:
先判斷元素的hashCode值是否相同,再判斷兩元素的equals方法是否為true
(往HashSet裡面存的自定義元素要複寫hashCode和equals方法,
以保證元素的唯一性!)
|--->TreeSet:底層資料結構式二叉樹。可以對Set集合中的元素進行排序。元素有序、執行緒不同步。
保證元素唯一性的依據:compareTo方法return 0
TreeSet排序的第一種方式:讓元素自身具備比較性,比如八種基本資料型別或則字串,
實現Compareble介面,覆蓋compareTo方法,
此方式是元素的自然順序
TreeSet排序的第一種方式:當元素自身不具備比較性(比如儲存學生物件時)或者具備的
比較性不是我們所需要的比較性時(比如想字串的長度排序),
此時就需要讓集合自身具備自定義的比較性。
那如何讓集合自身具備比較性呢?可在集合初始化時,
就讓集合具備比較方式。即定義一個類,
實現Comparator介面,覆蓋compare方法。

**Set集合使用注意事項:
(1)HashSet:
通過new的方式往HashSet裡面存的元素的hashCode都不同,但通常我們定義物件,
比如學生物件時,雖然是new的兩個學生物件,但是當他們name和age一樣時,我們認為是
同一個物件,所以為了保證元素的唯一性,我們通常在往HashSet集合裡面儲存元素時,
在定義物件的類中通常複寫hashCode和equals方法。

 1 public int hashCode()
 2 {
 3 return name.hashCode()+age*39;
 4 }
 5 public boolean equals(Object obj)
 6 {
 7 if(!(obj instanceof Student))
 8 return false;
 9 Student stu = (Student)obj;
10 return this.name.equals(stu.name)&&this.age==stu.age;
11 }

HashSet是如何保證元素唯一性的呢?
如果兩元素的hashCode值不同,則不會呼叫equals方法

如果兩元素的hashCode值相同,則繼續判斷equals是否返回true;
**hashCode和equals方法雖然定義在自定義物件類裡面,但不是我們手動呼叫
而是往HashSet集合裡面儲存元素的時候,集合底層自己呼叫hashCode和equals
它自己拿物件去判斷,自己判斷兩元素是否是同一個元素。

(2)TreeSet:
TreeSet要求往裡面存的元素具備比較性,否則會報錯。
TreeSet排序的第一種方式:讓元素自身具備比較性
定義物件類,實現Compareble介面,複寫compareTo方法,此方式是元素的自然順序

1 class Student implements Comparable
 2 {
 3 private String name;
 4 private int age;
 5 public Student(String name,int age)
 6 {
 7 this.name=name;
 8 this.age=age;
 9 }
10 public String getName()
11 {
12 return name;
13 }
14 public int getAge()
15 {
16 return age;
17 }
18 public int compareTo(Object obj)
19 {
20 if(!(obj instanceof Student))
21 throw new RuntimeException("不是學生物件!");
22 Student stu = (Student)obj;
23 int num = this.age-stu.age;
24 if(num==0)
25 return this.name.compareTo(stu.name);
26 return num;
27 }
28 }java

TreeSet排序的第一種方式:讓集合具備比較性
當元素自身不具備比較性(比如儲存學生物件時)或者具備的
比較性不是我們所需要的比較性時(比如想字串的長度排序),
此時就需要讓集合自身具備自定義的比較性。
那如何讓集合自身具備比較性呢?可在集合初始化時,
就讓集合具備比較方式。即定義一個類,
實現Comparator介面,覆蓋compare方法。

1 class StringLengthComparator implements Comparator
 2 {
 3 public int compare(Object obj1,Object obj2)
 4 {
 5 String s1 = (String)obj1;
 6 String s2 = (String)obj2;
 7 int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
 8 if(num==0)
 9 return s1.compareTo(s2);
10 return num;
11 }
12 }
13 class TreeSetTest
14 {
15 public static void main(String[] args)
16 {
17 TreeSet ts = new TreeSet(new StringLengthComparator());
18 ts.add("addfg");
19 ts.add("dfg");
20 ts.add("agtuug");
21 ts.add("vgjkg");
22 sop(ts);
23 }
24 }

基本資料型別或字串物件均實現了Comparable介面,故同種型別基本資料間具備比較性,即自然順序。

**Map:頂層介面,該集合儲存的是鍵值對,而且鍵是唯一的,Map和Set很像,Set集合底層就是使用了Map集合。
Map集合沒有迭代器,要取出元素必須先將Map集合轉換成Set集合才能遍歷元素
|--->HashTable(JDK1.0):
底層是雜湊表資料結構;
不可以使用null鍵和null值;
用作鍵的物件必須實現hashCode和equals方法來保證鍵的唯一性
執行緒同步,效率低
|--->HashMap(JDK1.2):
底層是雜湊表資料結構;
允許使用null鍵和null值;
執行緒不同步,效率高;
保證元素唯一性的:
原理:先判斷元素的hashCode值是否相同,再判斷兩元素的equals方法是否為true
(往HashSet裡面存的自定義元素要複寫hashCode和equals方法,
以保證元素的唯一性!)

1 class Student {
  2 private String name;
  3 private int age;
  4 public Student(String name, int age) {
  5 super();
  6 this.name = name;
  7 this.age = age;
  8 }
  9 public int getAge() {
 10 return age;
 11 }
 12 public void setAge(int age) {
 13 this.age = age;
 14 }
 15 public String getName() {
 16 return name;
 17 }
 18 public void setName(String name) {
 19 this.name = name;
 20 }
 21 
 22 @Override
 23 public int hashCode(){
 24 return name.hashCode()+age*34;
 25 }
 26 @Override
 27 public boolean equals(Object obj){
 28 
 29 if(!(obj instanceof Student))
 30 return false;
 31 Student stu = (Student)obj;
 32 return this.name.equals(stu.name)&&this.age==stu.age;
 33 }
 34 public class HashMapDemo1 {
 35 public static void main(String[] args) {
 36 Map<Student , String> hmap = new HashMap<Student , String>();
 37 hmap.put(new Student("001",20), "beijing");
 38 hmap.put(new Student("002",25), "hebei");
 39 hmap.put(new Student("003",50), "hainan");
 40 hmap.put(new Student("001",20), "beijing");
 41 
 42 System.out.println(hmap.size());
 43 Set<Student> keySet = hmap.keySet();
 44 Iterator<Student> it = keySet.iterator();
 45 while(it.hasNext()){
 46 Student stu = it.next();
 47 String addr = hmap.get(stu);
 48 System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);
 49 }    
 50 }    
 51 }    
 52 |--->TreeMap(JDK1.0):
 53 底層是二叉樹結構;
 54 允許使用null鍵和null值;
 55 執行緒不同步;
 56 可以給Map集合中的鍵進行排序.
 57 TreeMap排序的第一種方式:讓元素自身具備比較性,比如八種基本資料型別或則字串,
 58 實現Compareble介面,覆蓋compareTo方法,
 59 此方式是元素的自然順序    
 60 TreeMap排序的第一種方式:當元素自身不具備比較性(比如儲存學生物件時)或者具備的
 61 比較性不是我們所需要的比較性時(比如想字串的長度排序),
 62 此時就需要讓集合自身具備自定義的比較性。 
 63 那如何讓集合自身具備比較性呢?可在集合初始化時,
 64 就讓集合具備比較方式。即定義一個類,
 65 實現Comparator介面,覆蓋compare方法。
 66 class Student implements Comparable<Student>{
 67 private String name;
 68 private int age;
 69 public Student(String name, int age) {
 70 super();
 71 this.name = name;
 72 this.age = age;
 73 }
 74 public int getAge() {
 75 return age;
 76 }
 77 public void setAge(int age) {
 78 this.age = age;
 79 }
 80 public String getName() {
 81 return name;
 82 }
 83 public void setName(String name) {
 84 this.name = name;
 85 }
 86 @Override
 87 public int compareTo(Student stu) {
 88 int num = new Integer(this.age).compareTo(new Integer(stu.age));
 89 if(num==0)
 90 return this.name.compareTo(stu.name);
 91 return num;
 92 }    
 93 }
 94 
 95 public class HashMapDemo1 {
 96 public static void main(String[] args) {
 97 
 98 Map<Student , String> tmap = new TreeMap<Student , String>();
 99 tmap.put(new Student("001",20), "beijing");
100 tmap.put(new Student("002",25), "hebei");
101 tmap.put(new Student("003",50), "hainan");
102 tmap.put(new Student("001",20), "beijing");
103 
104 System.out.println(tmap.size());
105 Set<Student> keySet1 = tmap.keySet();
106 Iterator<Student> it1 = keySet1.iterator();
107 while(it1.hasNext()){
108 Student stu = it1.next();
109 String addr = tmap.get(stu);
110 System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);    
111 }
112 }
113 }

Iterator:對collection進行迭代的迭代器.迭代器取代了Enumeration。
迭代器和列舉的區別:
迭代器允許呼叫者利用定義良好的語義在迭代期間從迭代器所指向的collection移除元素
方法名稱得到了改進,簡化書寫

LisIterator:系列表迭代器,允許程式設計師按任一方向遍歷列表、迭代期間修改列表
Comparable:此介面強行對實現它的每個類的物件進行整體自然排序。使元素具備比較性

Comparator:強行對某個物件collection進行整體排序的比較函式,使集合具備比較性
Collections:此類完全由在 collection 上進行操作或返回 collection 的靜態方法組成。

Arrays:此類包含用來運算元組(比如排序和搜尋)的各種靜態方法

7、集合類各容器方法:
介面Collection方法摘要(沒有構造方法)
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與指定物件是否相等
m. boolean isEmpty():判斷是否集合為空
d)獲取:
h. Iterator iterator():取出
i. int hashCode():返回此collection的雜湊值
j. int size():返回此collection中元素的個數
k. boolean retainAll(Collection c):取交集
m. Object toArray():返回此collection中所有元素的陣列
n. T[] toArray(T[] a):返回包含此collection中所有元素的數值。
***List集合子類及其方法
(1)List介面是Collection介面的一個子介面。
(2)List介面中的元素有如下特點(對角標的操作都是特有方法,因為有序):
A:元素有序(儲存順序和取出順序一致)
B:元素可以重複
(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):從一個大的List中擷取一個小的List
G:listIterator():返回一個List介面特有的迭代器
(1)、ArrayList:
|--->構造方法摘要:(少用,不是重點)
ArrayList():構造一個初始容量為 10 的空列表。
ArrayList(Collection<? extends E> c): 構造一個包含指定 collection 的元素的列表,
ArrayList(int initialCapacity): 構造一個具有指定初始容量的空列表。
|--->方法摘要:
|--->新增:
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
中的所有元素插入到此列表中。
|--->刪除:
void clear(): 移除此列表中的所有元素。
E remove(int index): 移除此列表中指定位置上的元素。
boolean remove(Object o): 移除此列表中首次出現的指定元素(如果存在)。
protected void removeRange(int fromIndex, int toIndex):
移除列表中索引在 fromIndex(包括)和 toIndex(不包括)之間的所有元素。
boolean removeAll(Collection<?> c): 從列表中移除指定 collection 中包含的其所有元素
|--->獲取:
E get(int index): 返回此列表中指定位置上的元素。
int indexOf(Object o): 返回此列表中首次出現的指定元素的索引,或如果此列表不包含元素,則返回 -1。
int lastIndexOf(Object o) 返回此列表中最後一次出現的指定元素的索引,或如果此列表不包含索引,則返回 -1。
public List subList(int fromIndex,int toIndex): 返回列表中指定的 fromIndex(包括 ) 和 toIndex(不包括)之間的部分檢視。
Iterator iterator(): 返回按適當順序在列表的元素上進行迭代的迭代器。
ListIterator listIterator(int index):返回列表中元素的列表迭代器(按適當順序),從列表的指定位置開始。
|--->修改:(特有方法!!)
E set(int index, E element): 用指定的元素替代此列表中指定位置上的元素。
(2)LinkedList:
|--->構造方法摘要:
LinkedList(): 構造一個空列表。
LinkedList(Collection<? extends E> c): 構造一個包含指定 collection 中的元素的列表,
這些元素按其 collection 的迭代器返回的順序排列。
|--->方法摘要:(特有的)
|--->新增
void addFirst(E e): 將指定元素插入此列表的開頭。
void addLast(E e): 將指定元素新增到此列表的結尾。
|--->獲取元素,但不刪除元素
E get(int index): 返回此列表中指定位置處的元素。
E getFirst(): 返回此列表的第一個元素。
E getLast(): 返回此列表的最後一個元素。
|--->獲取元素且刪除元素
E remove(): 獲取並移除此列表的頭(第一個元素)。
E remove(int index): 移除此列表中指定位置處的元素。
boolean remove(Object o): 從此列表中移除首次出現的指定元素(如果存在)。
E removeFirst(): 移除並返回此列表的第一個元素。
E removeLast(): 移除並返回此列表的最後一個元素。
|--->修改
E set(int index, E element) 將此列表中指定位置的元素替換為指定的元素。
(3)Vector
|--->構造方法摘要:
Vector(): 構造一個空向量,使其內部資料陣列的大小為 10,其標準容量增量為零。
Vector(Collection<? extends E> c): 構造一個包含指定 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 elements(): 返回此向量的元件的列舉。
Vector特有的取出方式:
列舉和迭代器很像,其實列舉和迭代器是一樣的,只是因為列舉的名稱和方法的名稱
名字都過長,所以列舉被迭代器取代了。
|--->列舉Enumeration的方法摘要:
boolean hasMoreElements(): 測試此列舉是否包含更多的元素。
E nextElement(): 如果此列舉物件至少還有一個可提供的元素,
則返回此列舉的下一個元素。
*Set集合子類及其方法
(1)HashSet:它不保證set的迭代順序;特別是它不保證該順序恆久不變.此類允許使用null元素。
|--->構造方法:
HashSet() 構造一個新的空 set,其底層 HashMap 例項的預設初始容量是 16,載入因子是 0.75。
HashSet(Collection<? extends E> c) 構造一個包含指定 collection 中的元素的新 set。
|--->方法摘要:
boolean add(E e) 如果此 set 中尚未包含指定元素,則新增指定元素。
void clear() 從此 set 中移除所有元素。
Object clone() 返回此 HashSet 例項的淺表副本:並沒有複製這些元素本身。
boolean contains(Object o) 如果此 set 包含指定元素,則返回 true。
boolean isEmpty() 如果此 set 不包含任何元素,則返回 true。
Iterator iterator() 返回對此 set 中元素進行迭代的迭代器。
boolean remove(Object o) 如果指定元素存在於此 set 中,則將其移除。
int size() 返回此 set 中的元素的數量(set 的容量)。
(2)TreeSet:使用元素的自然順序對元素進行排序,或者根據建立 set 時提供的 Comparator 進行排序.
|--->構造方法:
TreeSet() 構造一個新的空 set,該set根據其元素的自然順序進行排序。
TreeSet(Collection<? extends E> c)
構造一個包含指定 collection 元素的新 TreeSet,它按照其元素的自然順序進行排序。
TreeSet(Comparator<? super E> comparator) 構造一個新的空 TreeSet,它根據指定比較器進行排序。
|--->方法摘要:
新增:
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() 獲取並移除第一個(最低)元素;如果此 set 為空,則返回 null。
E pollLast() 獲取並移除最後一個(最高)元素;如果此 set 為空,則返回 null。
獲取:
Iterator iterator() 返回在此 set 中的元素上按升序進行迭代的迭代器。
E first() 返回此 set 中當前第一個(最低)元素。
E last() 返回此 set 中當前最後一個(最高)元素。
int size() 返回 set 中的元素數(set 的容量)。
判斷:
boolean isEmpty() 如果此 set 不包含任何元素,則返回 true。
boolean contains(Object o) 如果此 set 包含指定的元素,則返回 true。
**Map:將鍵對映到值的物件。Map集合沒有迭代器!Map集合特點:該集合儲存鍵值對。而且鍵是唯一的。
|--->方法摘要:
|--->新增:
V put(K key, V value) 將指定的值與此對映中的指定鍵關聯(可選操作)。
void putAll(Map<? extends K,? extends V> m) 從指定對映中將所有對映關係複製到此對映中
|--->刪除:
void clear() 從此對映中移除所有對映關係(可選操作)。
V remove(Object key) 如果存在一個鍵的對映關係,則將其從此對映中移除(可選操作)。
|--->判斷
boolean containsKey(Object key) 如果此對映包含指定鍵的對映關係,則返回 true。
boolean containsValue(Object value) 如果此對映將一個或多個鍵對映到指定值,則返回 true。
boolean isEmpty() 如果此對映未包含鍵-值對映關係,則返回 true。
|--->獲取
int size() 返回此對映中的鍵-值對映關係數。
Collection values() 返回此對映中包含的值的 Collection 檢視。

重點:Map集合沒有迭代器,以下是Map的兩種取出方式:
第一種:Set keySet()
返回此對映中包含的鍵的Set檢視,將Map集合中所有的鍵存入Set集合,然後再通過Set集合的
迭代器取出所有的鍵,再根據get方法獲取每個鍵的值;
第二種:Set<Map.Entry<K,V>> entrySet()
返回此對映中包含的對映關係的Set檢視,將Map集合中的對映關係存入到Set集合中,
這個對映關係的資料型別是Map.entry,再通過Map.Entry類的方法再要取出關係裡面的鍵和值
Map.Entry的方法摘要:
boolean equals(Object o) 比較指定物件與此項的相等性。
K getKey() 返回與此項對應的鍵。
V getValue() 返回與此項對應的值。
int hashCode() 返回此對映項的雜湊碼值。
V setValue(V value) 用指定的值替換與此項對應的值(特有!!!)。
8、Map集合和Collection集合的區別?
1,
Map中一次儲存是鍵值對。
Collection中一次儲存是單個元素。
2,
Map的儲存使用的put方法。
Collection儲存使用的是add方法。
3,
Map集合沒有迭代器,Map的取出,是將Map轉成Set,在使用迭代器取出。
Collection取出,使用就是迭代器。
4,
如果物件很多,必須使用集合儲存。
如果元素存在著對映關係,可以優先考慮使用Map儲存或者用陣列,
如果沒有對映關係,可以使用Collection儲存。
8、迭代器:Iterator(Map集合沒有迭代器)
(1)迭代器就是取出集合元素的方式
(2)迭代器的作用
因為每個集合中元素的取出方式都不一樣,於是就把元素的取出方式進行抽取,並定義在集合內部,
這樣取出方式就可以直接訪問集合內部的元素;
而每個容器的資料結構不同,所以取出動作的細節也不一樣,但是有共性內容:判斷和取出。
那麼就將共性內容進行抽取,從而形成了介面Iterater
(3)獲取迭代器的方法:
Iterator iterator() 返回在此 collection 的元素上進行迭代的迭代器。
Iterator iterator() 返回在此 set 中的元素上進行迭代的迭代器。
(3)迭代器方法:
boolean hasNext() 如果仍有元素可以迭代,則返回 true。
E next() 返回迭代的下一個元素。
void remove() 從迭代器指向的collection中移除迭代器返回的最後一個元素(可選操作)。
9、列表迭代器:ListIterator
(1)List集合特有的迭代器ListIterator是Iterator的子介面,在迭代時,不可以通過集合物件的
方法操作集合中的元素,因為會發生ConcurrentModificationException(當方法檢測到物件的併發修改,
但不允許這種修改時,丟擲此異常)
(2)Iterator方法有限,只能對元素進行判斷、取出和刪除的操作
ListIterator可以對元素進行新增和修改動作等。
(3)獲取列表迭代器方法:
ListIterator listIterator() 返回此列表元素的列表迭代器(按適當順序)。
ListIterator listIterator(int index)
返回此列表中的元素的列表迭代器(按適當順序),從列表中指定位置開始。
(4)列表迭代器方法:
void add(E e) 將指定的元素插入列表(可選操作)。
boolean hasPrevious() 如果以逆向遍歷列表,列表迭代器有多個元素,則返回 true。
int nextIndex() 返回對 next 的後續呼叫所返回元素的索引。
E previous() 返回列表中的前一個元素。
int previousIndex() 返回對 previous 的後續呼叫所返回元素的索引。
void set(E e) 用指定元素替換 next 或 previous 返回的最後一個元素(可選操作)。
10、堆疊和佇列
堆疊:先進後出,比如杯子裡的水
佇列:先進先出,比如水管的水
11、集合類各種容器的使用注意細節:
(1)迭代器:
迭代器的next方法是自動向下取元素,要避免出現NoSuchElementException。
也就是在迭代迴圈中呼叫一次next方法一次就要hasNext判斷一次,比如語句
sop(it.next()+"..."+it.next())會發生上述異常。

迭代器的next方法返回值型別是Object,所以要記得型別轉換,應用泛型後就不用強轉
(2)List集合:
List集合裡面的元素因為是帶角標,所以List集合裡面的元素都是有序的,
另外List集合可以包含重複元素,也可以包含null。

List集合有迭代器Iterator,還有一個特有迭代器列表ListIterator
List集合中判斷元素是否相同都是用equals方法,無論contains、remove都依賴equals方法
比如往ArrayList集合裡面存放學生,同名同年齡視為同一個人,此時就需要在學生類複寫Object類
裡面的equals方法(非常重要!!!要注意!!)
(3)Set集合:

Set接口裡面存放的是元素是無序的,不可以有重複元素,可以包含null
Set集合只有一種取出方式,就是迭代器Iterator

Set集合功能和Collection是一致的,沒有特殊方法
|--->HashSet:
集合裡面存放的元素是無序的,唯一的

底層資料結構是雜湊表,雜湊表結構的資料都是無序的,雜湊表結構的操作效率都高效
執行緒不同步

保證元素唯一性的原理是:通過複寫hashCode和equals方法
如果兩元素的hashCode值相同,則繼續判斷兩元素equals是否為真
如果兩元素的hashCode值不同,則不會呼叫equals方法。
當我們往HashSet集合存放自定義的元素時(比如學生物件),通常都要複寫hashCode和equals方法,
而且hashCode和equals方法不通過我們呼叫,HashSet集合底層內部自己呼叫,自己拿元素去比較
|--->TreeSet

TreeSet集合可以對存放的元素進行排序,彌補了Set集合元素無序的缺點,且元素是唯一的
底層資料結構是二叉樹,二叉樹結構都是有序的

執行緒不同步
TreeSet集合要求往集合裡存放的元素自身具備比較性,否則會報錯

TreeSet集合保證元素唯一性的依據是:通過compareTo或者compare方法中的來保證元素的唯一性。
TreeSet排序的第一種方式:讓元素自身具備比較性,
定義元素類實現Compareble介面,覆蓋compare方法,
此方式是元素的自然順序。
TreeSet排序的第二種方式:讓集合具備比較性
當元素自身不具備比較性或者具備的比較性不是
我們所需要的比較性時,此時就需要讓集合具備自定義的比較性。
那如何讓集合自身具備比較性呢?
可在集合初始化時,就讓集合具備比較方式。
即定義一個類,實現Comparator介面,覆蓋compare方法。
注:
判斷元素唯一時,當主要條件一樣時,判斷次要條件

兩種排序方式都在時,以比較器為主!!!
(4)Map集合:
|--Hashtable
底層是雜湊表結構
執行緒安全的,並且鍵和值不能為null。
|--HashMap
底層是雜湊表結構
執行緒不安全的,鍵和值可以為null。
|--LinkedHashMap
底層是連結串列和雜湊表
執行緒不安全
|--TreeMap
底層是二叉樹
執行緒不安全的
12、如果你想將一組物件按一定順序存取,在不考慮併發訪問的情況下會使用C_ ,
反之則會使用A_;如果你想儲存一組無序但唯一的物件,你會使用B_ ;
如果你想按關鍵字對物件進行存取,在不考慮併發訪問的情況下會使用_D__ ,反之則會使用_E。
A. Vector
B. HashSet
C. ArrayList
D. HashMap
E. Hashtable
13、泛型:
(1)為什麼會出現泛型?
因為集合存放的資料型別不固定,故往集合裡面存放元素時,存在安全隱患,
如果在定義集合時,可以想定義陣列一樣指定資料型別,那麼就可以解決該類安全問題。
JDK1.5後出現了泛型,用於解決集合框架的安全問題。
泛型是一個型別安全機制。
(2)泛型定義格式:通過<>來定義要操作的引用資料型別
ArrayList al = new ArrayList;
(3)泛型的好處:
將執行時期出現的ClassCastException(型別轉換異常)問題轉移到編譯時期;

避免了強制轉換的麻煩
(4)什麼時候定義泛型?
泛型在集合框架中很常見,只要見到<>就要定義泛型。其實<>就是用來接收型別的。
當使用集合時,將集合中要儲存的資料型別作為引數傳遞到<>中即可
(5)泛型的形式
泛型類:即自定義泛型類
A:當類中要操作的引用資料型別不確定時,早起定義Object來完成擴充套件,現在定義泛型來完成
B:侷限性:泛型類定義的泛型,在整個類中有效,如果該泛型類的方法被呼叫,
當泛型類的物件明確要操作的型別後,所有要操作的型別就被固定。

泛型方法:泛型放在返回值前面,修飾符的後面
A:為了避免泛型類的侷限性,讓不同方法可以操作不同的型別,而且型別還不確定,
則可以將泛型定義在方法上
B:特殊之處:靜態方法不可以反問類上定義的泛型
如果靜態方法操作的應用資料型別不確定,可以講泛型定義在靜態方法上
泛型介面:
當泛型定義在介面上時,則子類中要指定實現介面型別,同時還可以子類也可以定義為泛型類
(6)泛型的高階應用:?萬用字元

當指定兩種泛型的集合,則迭代時也要定義兩種泛型的迭代器,麻煩,此時可通過將迭代器的泛型
改為?,如Iterator<?> it=al.iterator();
**兩種泛型限定
向上限定: ? extends E ;E可以接收E型別或者E的子類
向下限定: ? super E ;E可以接收E型別或者E的父類
14、高階for迴圈
(1)JDK1.5新特性,代替迭代器使用時的不爽,簡化書寫,底層原理是迭代器凡是支援迭代器的都支援高階for迴圈
高階for迴圈,只用於集合和陣列的遍歷,集合只能用Collection不能用Map集合
只能把Map集合轉化成Set集合,才能用for迴圈。
(2)格式
for(資料型別 變數名:被遍歷的集合(Collection)或者陣列)
{

}
(3)侷限性:
必須要有遍歷的目標
對集合或者陣列進行遍歷時,只能獲取集合元素,不能對集合元素進行操作
迭代器除了遍歷,還可以進行remove操作集合中的元素
列表迭代器還可以在遍歷過程中進行增刪改查的操作
(4)傳統for迴圈和高階for迴圈的區別
高階for迴圈有一個侷限性,就是必須要有遍歷的目標(集合或者陣列)
遍歷陣列時建議使用傳統for迴圈,因為可以定義角標,比如列印100次helloworld時用傳統for迴圈方便
15、可變引數
(1)陣列的可變引數
格式:
int... arr
(3)方法的可變引數
格式:
public static void show(String str,int... arr)
{

}
注意:可變引數一定要放在引數列表的最後面
16、靜態匯入:
import static java.util.Arrays.* 匯入的是Arrays這個類中所有的靜態方法

當類名重名時,需要制定具體的報名
**當方法重名時,需要制定具體所屬的物件或者類
17、Collections類:
(1)此類完全由在 collection 上進行操作或返回 collection 的靜態方法組成。
(2)靜態方法摘要:
static boolean addAll(Collection<? super T> c, T... elements)
將所有指定元素新增到指定 collection 中。
static void fill(List<? super T> list, T obj)
使用指定元素替換指定列表中的所有元素。
static boolean replaceAll(List list, T oldVal, T newVal)
使用另一個值替換列表中出現的所有某一指定值。
static void reverse(List<?> list)
反轉指定列表中元素的順序。
static Comparator reverseOrder()
返回一個比較器,它強行逆轉實現了 Comparable 介面的物件 collection 的自然順序
static Comparator reverseOrder(Comparator cmp)
返回一個比較器,它強行逆轉指定比較器的順序。
(3)Collections類特牛的方法:
集合有一個共同的缺點,那就是執行緒不安全,被多執行緒操作時,容易出現問題,雖然可以自己加鎖
但是麻煩。Collections提供特牛的方法,就是給它一個不同步的集合,它返回一個同步的安全的集合

static Collection synchronizedCollection(Collection c)
返回指定 collection 支援的同步(執行緒安全的)collection。
static List synchronizedList(List list)
返回指定列表支援的同步(執行緒安全的)列表。
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
返回由指定對映支援的同步(執行緒安全的)對映。
static Set synchronizedSet(Set s)
返回指定 set 支援的同步(執行緒安全的)set。
static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
返回指定有序對映支援的同步(執行緒安全的)有序對映。
static SortedSet synchronizedSortedSet(SortedSet s)
返回指定有序 set 支援的同步(執行緒安全的)有序 set。
18、Arrays類:
此類包含用來運算元組(比如排序和搜尋)的各種方法。裡面都是靜態方法。
如果指定陣列引用為 null,則此類中的方法都會丟擲 NullPointerException。
(1)靜態方法摘要:
static List asList(T... a)
返回一個受指定陣列支援的固定大小的列表。
注意:
A:該方法將一個數組變成集合後,不可以使用集合的增刪方法,因為陣列的長度是固定的!
如果增刪,則發生UnsupportedOprationException(不支援操作異常)
B:如果陣列中的元素都是基本資料型別,則該陣列變成集合時,會將該陣列作為集合的一個
元素出入集合
C:如果陣列中的元素都是物件,如String,那麼陣列變成集合後,陣列中的元素就直接轉成
集合中的元素
19、陣列變集合以及集合變陣列的對比:
(1)陣列變集合:
方法:static List asList(T... a) 返回一個受指定陣列支援的固定大小的列表。
好處:可以使用集合的思想和方法運算元組中的元素,陣列是一個物件,但是陣列中的功能很少
(2)集合變陣列:
方法:Collction中的toArray方法
好處:可以限定對集合元素的操作,防止對集合的元素進行增刪,因為陣列長度是固定的。

20、Collections類和Arrays類的使用。(重點)
A:Collections
排序
二分查詢
發轉
B:Arrays
把陣列變成字串輸出
排序
二分查詢
21、System:
(1)描述系統資訊的類
(2)該類沒有構造方法,該類的方法和屬性都是靜態的
(3)欄位摘要:
static InputStream in “標準”輸入流。
static PrintStream out “標準”輸出流。
(4)方法摘要:
static void exit(int status) 終止當前正在執行的 Java 虛擬機器。
static void gc() 執行垃圾回收器。
static Properties getProperties() 確定當前的系統屬性
static String getProperty(String key) 獲取指定鍵指示的系統屬性。
static String getProperty(String key, String def) 獲取用指定鍵描述的系統屬性。
static void setIn(InputStream in) 重新分配“標準”輸入流。
static void setOut(PrintStream out) 重新分配“標準”輸出流。
static void setProperties(Properties props) 將系統屬性設定為 Properties 引數。
static String setProperty(String key, String value) 設定指定鍵指示的系統屬性。
22、Runtime:
(1)每個 Java 應用程式都有一個 Runtime 類例項,使應用程式能夠與其執行的環境相連線。
可以通過 getRuntime 方法獲取當前執行時。 應用程式不能建立自己的 Runtime 類例項。
(2)該類沒有建構函式,也就是它不能直接建立物件,但是它裡裡面的方法又不是靜態的
,故它一定有一個方法返回本類物件
(3)故該類是單例設計模式,保證在記憶體中只有一個物件
(4)方法摘要:
Process exec(String command) 在單獨的程序中執行指定的字串命令
void gc() 執行垃圾回收器。
static Runtime getRuntime() 返回與當前 Java 應用程式相關的執行時物件
void exit(int status) 通過啟動虛擬機器的關閉序列,終止當前正在執行的 Java 虛擬機器
23、Date:
(1)Date介面表示特定的瞬間,精確到毫秒
(2)構造方法
Date() 分配 Date 物件並初始化此物件,以表示分配它的時間(精確到毫秒)。
Date(long date) 分配Date物件並初始化此物件,以表示自從標準基準時間(稱為“曆元(epoch)”,
即1970年1月1日00:00:00GMT)以來的指定毫秒數。
(3)方法摘要:
int compareTo(Date anotherDate) 比較兩個日期的順序。
boolean equals(Object obj) 比較兩個日期的相等性。
24、Calendar:
(1)直接已知子類: GregorianCalendar
(2)構造方法:
protected Calendar() 構造一個帶有預設時區和語言環境的 Calendar。
protected Calendar(TimeZone zone, Locale aLocale) 構造一個帶有指定時區和語言環境的 Calendar。
(3)方法摘要:
static Calendar getInstance() 使用預設時區和語言環境獲得一個日曆。

四、jdk1.5的新特性
(1)靜態匯入:
import語句可以匯入一個類或某個包中的所有類

import static語句匯入一個類中的某個靜態方法或所有靜態方法
靜態匯入後,靜態方法前面就不用寫類名.方法的方式類呼叫
語法舉例:
import static java.lang.Math.sin;//匯入一個靜態方法
import static java.lang.Math.*; //匯入一個類中的所有靜態方法

靜態匯入使用注意:
當類名重複時,需要制定具體的包名;
當方法重名時,需要制定具體所屬的物件或者類
(2)可變引數:
可變引數的特點:
*可變引數只能出現在引數列表的最後;
*...位於變數型別和變數名之間,前後有無空格都可以;
*呼叫可變引數的方法時,編譯器為該可變引數隱含建立一個數組,
在方法體中以陣列的形式訪問可變引數。

可變引數舉例:
*變數型別... 變數名 如 int... arr 表示可變引數陣列
*public static void show(String str , int... arr){}
(3)增強for迴圈:
語法:
for ( type 變數名:集合變數名 ) { … }

注意事項:
迭代變數必須在( )中定義!
集合變數可以是陣列或實現了Iterable介面的集合類
舉例:
public static int add(int x,int ...args) {
int sum = x;
for(int arg:args) {
sum += arg;
}
return sum;
}

增強for迴圈代替了迭代器使用的不爽,簡化書寫
增強for迴圈侷限性:
對集合或者陣列進行遍歷時,只能取元素,不能對集合進行操作
(4)基本資料型別的自動裝箱和拆箱

基本資料型別
byte ---> Byte
short ---> Short
int ---> Integer
long ---> Long
float ---> Float
double ---> Double
char ---> Character
boolean ---> Boolean
例子:

裝箱:自動把一個基本資料型別的資料裝箱成一個該型別資料的物件引用
Integer i = 3;(jdk1.5之前這樣寫是不行的,編譯報錯)
拆箱:自動把一個基本資料型別的物件引用拆箱成一個基本資料型別的資料,再參與運算
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而後面的運算返回false呢?
對於基本資料型別的整數,裝箱成Integer物件時,如果該數值在一個位元組內,(-128~127),
一旦裝箱成Integer物件後,就把它快取到磁裡面,當下次,又把該數值封裝成Integer物件時
會先看磁裡面有沒有該物件,有就直接拿出來用,這樣就節省了記憶體空間。因為比較小的整數,
用的頻率比較高,就沒必要每個物件都分配一個記憶體空間。
這就是享元模式!比如26個英文字母,10個阿拉伯數字
(5)列舉
**為什麼要有列舉?
問題:要定義星期幾或性別的變數,該怎麼定義?假設用1-7分別表示星期一到星期日,
但有人可能會寫成int weekday = 0;或即使使用常量方式也無法阻止意外。

列舉就是要讓某個型別的變數的取值只能為若干個固定值中的一個,否則,編譯器就會報錯。
列舉可以讓編譯器在編譯時就可以控制源程式中填寫的非法值,
普通變數的方式在開發階段無法實現這一目標。
用普通類如何實現列舉的功能?定義一個Weekday類來模擬實現:
步驟:
*私有化構造方法
*每個元素分別用一個公有的靜態成員變量表示(public static final)
*可以有若干公有方法或抽象方法。採用抽象方法定義nextDay就將大量的if.else語句
轉移成了一個個獨立的類。

列舉的應用:
舉例:定義一個Weekday的列舉。
擴充套件:列舉類的values,valueOf,name,toString,ordinal等方法
(記住,講課時要先於自定義方法前介紹,講課更流暢)
總結:列舉是一種特殊的類,其中的每個元素都是該類的一個例項物件。
例如可以呼叫WeekDay.SUN.getClass().getName和WeekDay.class.getName()。
列舉的高階應用:

列舉就相當於一個類,其中也可以定義構造方法、成員變數、普通方法和抽象方法。
列舉元素必須位於列舉體中的最開始部分,列舉元素列表的後要有分號與其他成員分隔。
把列舉中的成員方法或變數等放在列舉元素的前面,編譯器報告錯誤。

帶構造方法的列舉
構造方法必須定義成私有的
如果有多個構造方法,該如何選擇哪個構造方法?
列舉元素MON和MON()的效果一樣,都是呼叫預設的構造方法。
帶方法的列舉
定義列舉TrafficLamp
實現普通的next方法
實現抽象的next方法:每個元素分別是由列舉類的子類來生成的例項物件,
這些子類採用類似內部類的方式進行定義。增加上表示時間的構造方法

列舉只有一個成員時,就可以作為一種單例的實現方式。
(6)泛型:
泛型是提供給javac編譯器使用的,可以限定集合中的輸入型別,讓編譯器擋住源程式中的非法輸入,
編譯器編譯帶型別說明的集合時會去除掉“型別”資訊,使程式執行效率不受影響,
對於引數化的泛型型別,getClass()方法的返回值和原始型別完全一樣。
由於編譯生成的位元組碼會去掉泛型的型別資訊,只要能跳過編譯器,
就可以往某個泛型集合中加入其它型別的資料,例如,用反射得到集合,再呼叫其add方法即可。

ArrayList類定義和ArrayList類引用中涉及如下術語:
整個稱為ArrayList泛型型別
ArrayList中的E稱為型別變數或型別引數
整個ArrayList稱為引數化的型別
ArrayList中的Integer稱為型別引數的例項或實際型別引數
ArrayList中的<>念著typeof
ArrayList稱為原始型別
引數化型別與原始型別的相容性:
引數化型別可以引用一個原始型別的物件,編譯報告警告,
例如, Collection c = new Vector();//可不可以,不就是編譯器一句話的事嗎?
原始型別可以引用一個引數化型別的物件,編譯報告警告,
例如, Collection c = new Vector();//原來的方法接受一個集合引數,新的型別也要能傳進去

引數化型別不考慮型別引數的繼承關係:
Vector v = new Vector