JDK1.5新特性:
? ? 1.自動拆裝箱.
? ? 2.泛型
? ? 3.可變參數(shù)
? ? 4.靜態(tài)導(dǎo)入
? ? 5.增強for循環(huán)
? ? 6.互斥鎖
? ? 7.枚舉
8.注解
JDK1.6新特性:
1.Desktop類和SystemTray類
2.使用JAXB2來實現(xiàn)對象與XML之間的映射
3.StAX
4.使用Compiler API
5.輕量級Http Server API
6.插入式注解處理API(Pluggable Annotation Processing API)
7.用Console開發(fā)控制臺程序
8.對腳本語言的支持
9.Common Annotations
JDK1.7新特性:
1 對集合類的語言支持;
2 自動資源管理;
3 改進的通用實例創(chuàng)建類型推斷;
4 數(shù)字字面量下劃線支持;
5 switch中使用string;
6 二進制字面量0b001;
7 簡化可變參數(shù)方法調(diào)用。
8 泛型簡化,出現(xiàn)菱形泛型
9 異常的多個catch合并,每個異常用或|
10 try-with-resources 語句
JDK1.8 新特性:
一、接口的默認方法:Java 8允許我們給接口添加一個非抽象的方法實現(xiàn),只需要使用 default關(guān)鍵字即可,這個特征又叫做擴展方法,
二、Lambda 表達式:Collections.sort(names, (a, b) -> b.compareTo(a));Java編譯器可以自動推導(dǎo)出參數(shù)類型,所以你可以不用再寫一次類型。
三、函數(shù)式接口:每一個lambda表達式都對應(yīng)一個類型,通常是接口類型。而“函數(shù)式接口”是指僅僅只包含一個抽象方法的接口,每一個該類型的lambda表達式都會被匹配到這個抽象方法。
因為 默認方法 不算抽象方法,所以你也可以給你的函數(shù)式接口添加默認方法。
四、方法與構(gòu)造函數(shù)引用:Java 8 允許你使用 :: 關(guān)鍵字來傳遞方法或者構(gòu)造函數(shù)引用,上面的代碼展示了如何引用一個靜態(tài)方法,我們也可以引用一個對象的方法:
五、Lambda 作用域:在lambda表達式中訪問外層作用域和老版本的匿名對象中的方式很相似。你可以直接訪問標記了final的外層局部變量,或者實例的字段以及靜態(tài)變量。
六、訪問局部變量:lambda表達式中訪問外層的局部變量
七、訪問對象字段與靜態(tài)變量:lambda內(nèi)部對于實例的字段以及靜態(tài)變量是即可讀又可寫。該行為和匿名對象是一致的:
八、訪問接口的默認方法:Lambda表達式中是無法訪問到默認方法的
九、Date API:Java 8 在包java.time下包含了一組全新的時間日期API。新的日期API和開源的Joda-Time庫差不多,但又不完全一樣
十、Annotation 注解:在Java 8中支持多重注解了,Java 8允許我們把同一個類型的注解使用多次,只需要給該注解標注一下@Repeatable即可,
斷言的使用方式:
斷言是一種測試和調(diào)測階段所使用的戰(zhàn)術(shù)工具.
斷言的初衷:在一個具有自我保護能力的程序中,斷言很常用.假設(shè)確信某個屬性符合要求,并且代碼的執(zhí)行依賴于這個屬性.例如,需要計算
double y = Math.sqrt(x);
我們確信,這里的x是一個非負數(shù)的值.原因是:是另外一個計算的結(jié)果,而這個結(jié)果不可能是負值;或者x是一個方法的參數(shù),而這個方法要求它的調(diào)用者只能提供一個正整數(shù).
然而,還是希望進行檢查,以避免讓"不是一個數(shù)"的數(shù)值參與計算操作.當然,也可以拋出一個異常:
if(x<0) throw new IllegalArgumentException("x<0");
但是需要注意的是,這段代碼會一直保留在程序中,即使測試完畢也不會自動的刪除.如果在程序中包含有大量的這種檢查,程序運行起來會相當慢.
斷言機制允許在測試期間向代碼中插入一些檢查語句.當代碼發(fā)布時,這些插入的檢查語句將會被自動的移走.
開啟斷言:2.在myEclipse中,Windows -> Preferences ->Java ->Installed JREs ->點擊正使用的JDK ->Edit ->Default VM Arguments文本框中輸入:-ea或者-enableassertions
斷言的格式:
? ? java中語音引入關(guān)鍵字assert.這個關(guān)鍵字有兩種表現(xiàn)形式:
1.assert 條件:? 例如:assert x>=0;? 想要斷言x是一個非負數(shù)值,只需要簡單的使用這條語句.
2.assert 條件:表達式; 例如:assert x>=0 : x;? 或者將x的實際值傳遞給AssertionError對象,從而可以在后面顯示出來.
這兩個格式都會對條件進行檢測,如果結(jié)果為false,則拋出一個AssertionError異常.
在第二種格式中,表達式將被傳入AssertionEeror的構(gòu)造器,并轉(zhuǎn)換成一個消息字符串.
注釋:"表達式"部分的唯一目的是產(chǎn)生一個消息字符串.AssertionErro對象并不存儲表達式的值,因此,不可能在以后得到它.正如JDK文檔所描述的那樣:如果使用表達式的值,
就會鼓勵程序員試圖從斷言中恢復(fù)程序的運行,這不符合斷言機制的初衷.
啟用和禁用斷言
在默認情況下,斷言是被禁用的??梢栽诔绦蜻\行時用-enableassertions或-ea選項啟用它:
java -enableassertions MyApp
啟用或者禁用斷言不必重新編譯程序。啟動或者禁用斷言是類加載器的功能。當斷言被禁用時,類加載器將跳過斷言代碼,因此,不會降低程序的運行速度。
也可以在某個類或者某個包中使用斷言,例如:
java -ea:MyClass -ea:com.mycompany.mylib... MyApp
這條命令將開啟MyClass類以及在com.mycompany.mylib包和它的子包中的所有類的斷言。選項-ea將開啟默認包中的所有類的斷言。
也可以使用-disableassertions或-da禁用某個特定的類和包的斷言:
java -ea:... -da:MyClass MyApp
有些類不是由類加載器加載,而是直接由虛擬機加載。可以使用這些開關(guān)有選擇地啟用或禁用哪些類中的斷言。
然而,啟用和禁用所有斷言的-ea和-da開關(guān)并不能應(yīng)用到那些沒有類加載器的“系統(tǒng)類”上。對于這些系統(tǒng)類而言,需要使用-enablesystemassertions/-esa開關(guān)啟動斷言。
使用斷言完成參數(shù)檢查
API:java.long.ClassLoader 1.0? 子類MLet
void setDefaultAssertionStatus(Boolean b) //1.4
對于通過類加載器加載的所有類來說,如果沒有顯示的說明類或者包的斷言 狀態(tài),就啟用或禁用斷言.
void setClassAssertionSatus(String className,boolean b) //1.4
對于給定的類和它的內(nèi)部類,啟用或禁用斷言.
void setPackageAssertionStatus(String packageName,boolean b) //1.4
對于給定包和其子包中的所有類,啟用或禁用斷言.
void clearAssertionStatus()? //1.4
移去所有類和包的顯示斷言狀態(tài)設(shè)置,并禁用所有通過這個類加載器加載的類的斷言.
java中的3中處理系統(tǒng)錯誤的機制:
拋出一個異常
日志
使用斷言
什么時候應(yīng)該使用斷言呢?
斷言失敗是致命的、不可恢復(fù)的錯誤
斷言檢查只用于開發(fā)和測試階段
因此,不應(yīng)該使用斷言向程序的其他部分通告發(fā)生了可恢復(fù)性的錯誤,或者,不應(yīng)該作為程序向用戶通告問題的手段。斷言只應(yīng)該是在測試階段確定程序內(nèi)部錯誤的位置。
斷言是一種測試和調(diào)試階段所使用的戰(zhàn)術(shù)性工具;而日志記錄是一種在程序的整個生命周期都可以使用的策略性工具。
public class App
{
? ? public static void main( String[] args )
? ? {
? ? ? ? int a = -1;
? ? ? ? assert a > 0 : "liuni是笨蛋";
? ? ? ? System.out.println( "Hello World!" );
? ? }
}
程序中記錄日志一般有兩個目的:Troubleshooting和顯示程序運行狀態(tài)。好的日志記錄方式可以提供我們足夠多定位問題的依據(jù)。日志記錄大家都會認為簡單,但如何通過日志可以高效定位問題并不是簡單的事情。這里列舉下面三個方面的內(nèi)容,輔以代碼示例,總結(jié)如何寫好日志,希望對他人有所啟發(fā)和幫助:
怎樣記日志可以方便Troubleshooting
程序運行狀態(tài)可以記哪些
應(yīng)該避免怎樣的日志方式
怎樣記日志可以方便Troubleshooting?
1. 對外部的調(diào)用封裝
程序中對外部系統(tǒng)與模塊的依賴調(diào)用前后都記下日志,方便接口調(diào)試。出問題時也可以很快理清是哪塊的問題
[java] view plain copy
LOG.debug("Calling external system:" + parameters);? ?
? Object result = null;? ?
? try {? ?
? ? ? result = callRemoteSystem(params);? ?
? ? ? LOG.debug("Called successfully. result is " + result);? ?
? } catch (Exception e) {? ?
? ? ? LOG.warn("Failed at calling xxx system . exception : " + e);? ?
? }? ?
2.狀態(tài)變化
程序中重要的狀態(tài)信息的變化應(yīng)該記錄下來,方便查問題時還原現(xiàn)場,推斷程序運行過程
[java] view plain copy
boolean isRunning;? ?
isRunning = true;? ?
LOG.info("System is running");? ?
//...? ?
isRunning = false;? ?
LOG.info("System was interrupted by " + Thread.currentThread().getName());? ?
3.系統(tǒng)入口與出口:
這個粒度可以是重要方法級或模塊級。記錄它的輸入與輸出,方便定位
[java] view plain copy
void execute(Object input) {? ?
? ? ? LOG.debug("Invoke parames : " + input);? ?
? ? ? Object result = null;? ?
? ? ? //business logic?
? ? ? LOG.debug("Method result : " + result);? ?
? }? ?
4.業(yè)務(wù)異常:
任何業(yè)務(wù)異常都應(yīng)該記下來:
[java] view plain copy
try {? ?
? ? ? //business logical? ?
? } catch (IOException e) {? ?
? ? ? LOG.warn("Description xxx" , e);? ?
? } catch (BusinessException e) {? ?
? ? ? LOG.warn("Let me know anything");? ?
? } catch (Exception e) {? ?
? ? ? LOG.error("Description xxx", e);? ?
? }? ?
5.非預(yù)期執(zhí)行:
為程序在“有可能”執(zhí)行到的地方打印日志。如果我想刪除一個文件,結(jié)果返回成功。但事實上,那個文件在你想刪除之前就不存在了。最終結(jié)果是一致的,但程序得讓我們知道這種情況,要查清為什么文件在刪除之前就已經(jīng)不存在
[java] view plain copy
int myValue = xxxx;? ?
int absResult = Math.abs(myValue);? ?
if (absResult < 0) {? ?
? ? LOG.info("Original int " + myValue + "has nagetive abs " + absResult);? ?
}? ?
6.很少出現(xiàn)的else情況:
else可能吞掉你的請求,或是賦予難以理解的最終結(jié)果
[java] view plain copy
Object result = null;? ?
if (running) {? ?
? ? result = xxx;? ?
} else {? ?
? ? result = yyy;? ?
? ? LOG.debug("System does not running, we change the final result");? ?
}? ?
日志記錄:
程序運行狀態(tài)可以記哪些?
程序在運行時就像一個機器人,我們可以從它的日志看出它正在做什么,是不是按預(yù)期的設(shè)計在做,所以這些正常的運行狀態(tài)是要有的。
1. 程序運行時間:
[java] view plain copy
long startTime = System.currentTime();? ?
// business logical? ?
LOG.info("execution cost : " + (System.currentTime() - startTime) + "ms"); ? ?
2. 大批量數(shù)據(jù)的執(zhí)行進度:
[java] view plain copy
LOG.debug("current progress: " + (currentPos * 100 / totalAmount) + "%");? ?
3.關(guān)鍵變量及正在做哪些重要的事情:
執(zhí)行關(guān)鍵的邏輯,做IO操作等等
[java] view plain copy
String getJVMPid() {? ?
? ? String pid = "";? ?
? ? // Obtains JVM process ID? ?
? ? LOG.info("JVM pid is " + pid);? ?
? ? return pid;? ?
? }? ?
? void invokeRemoteMethod(Object params) {? ?
? ? ? LOG.info("Calling remote method : " + params);? ?
? ? //Calling remote server? ?
}? ?
應(yīng)該避免怎樣的日志方式?
1. 混淆信息的Log
日志應(yīng)該是清晰準確的: 當看到日志的時候,你知道是因為連接池取不到連接導(dǎo)致的問題么?
[java] view plain copy
Connection connection = ConnectionFactory.getConnection();? ?
if (connection == null) {? ?
? ? LOG.warn("System initialized unsuccessfully");? ?
}? ?
2. 記錯位置
產(chǎn)品代碼中,使用console記錄日志,導(dǎo)致沒有找到日志。
[java] view plain copy
} catch (ConfigurationException e) {?
? ? ? ? e.printStackTrace();?
? ? ? }?
3. 記錯級別
記錯級別常常發(fā)生,常見的如:混淆代碼錯誤和用戶錯誤,如登錄系統(tǒng)中,如果惡意登錄,那系統(tǒng)內(nèi)部會出現(xiàn)太多WARN,從而讓管理員誤以為是代碼錯誤。可以反饋用戶以錯誤,但是不要記錄用戶錯誤的行為,除非想達到控制的目的。
[java] view plain copy
LOG.warn("Failed to login by "+username+");?
4. 遺漏信息
這里可能包含兩種情況:(1)用戶自己少寫了信息,導(dǎo)致毫無參考價值;(2)用戶調(diào)用log的方式導(dǎo)致丟失信息,如下例,沒有stack trace.
[java] view plain copy
} catch (Exception ex) {?
? ? ? ? log.error(ex);?
? ? ? }?
*/
----------String--------------
構(gòu)造:
String(String original):把字符串數(shù)據(jù)封裝成字符串對象
String(char[] value):把字符數(shù)組的數(shù)據(jù)封裝成字符串對象
String(char[] value, int index, int count):把字符數(shù)組中的一部分數(shù)據(jù)
方法:
判斷功能:
boolean equals(Object obj):比較字符串的內(nèi)容是否相同
boolean equalsIgnoreCase(String str):比較字符串的內(nèi)容是否相同,忽略大小寫
? boolean startsWith(String str):判斷字符串對象是否以指定的str開頭
boolean endsWith(String str):判斷字符串對象是否以指定的str結(jié)尾
獲取功能:
int length():獲取字符串的長度,其實也就是字符個數(shù)
char charAt(int index):獲取指定索引處的字符
int indexOf(String str):獲取str在字符串對象中第一次出現(xiàn)的索引
String substring(int start):從start開始截取字符串
String substring(int start,int end):從start開始,到end結(jié)束截取字符串。包括start,不包括end
轉(zhuǎn)換功能:
char[] toCharArray():把字符串轉(zhuǎn)換為字符數(shù)組
String toLowerCase():把字符串轉(zhuǎn)換為小寫字符串
String toUpperCase():把字符串轉(zhuǎn)換為大寫字符串
String replace(char oldChar, char newChar)通過用 newChar 替換此字符串中出現(xiàn)的所有 oldChar ,返回處理后的字符串。
其它功能:
String trim():去除字符串兩端空格
String[] split(String str):按照指定符號分割字符串
--------StringBuider(可變字符串)------------
構(gòu)造:
就一個
方法:
public int capacity():返回當前容量 (理論值)
? ? public int length():返回長度(已經(jīng)存儲的字符個數(shù))
public StringBuilder append( 任意類型 ):添加數(shù)據(jù),并返回添加的數(shù)據(jù)
public StringBuilder reverse():反轉(zhuǎn)功能
StringBuilder replace(int start, int end, String str) 使用給定 String 中的字符替換此序列的子字符串中的字符。
--------Integer(包裝類)---------------
構(gòu)造:
不需要,直接類名.方法名調(diào)用,如下
方法:
Integer.parseInt(String str):將字符串轉(zhuǎn)int類型(只能數(shù)字內(nèi)容的字符串,不然報錯)
---------ArrayList(集合)-------------------
構(gòu)造:
ArrayList();就學(xué)了空參創(chuàng)建
方法:
public boolean add(E e):添加元素,成功返回true,就業(yè)班學(xué)false
public void add(int index,E element):在指定的索引處添加一個元素
public E get(int index):返回指定索引處的元素
public E set(int index,E element):修改指定索引處的元素,返回被修改的元素
public int size():返回集合中的元素的個數(shù)
public boolean remove(Object o):刪除指定的元素,返回刪除是否成功
E remove(int index) 移除此列表中指定位置上的元素,并返回刪除的數(shù)據(jù)。
---------FileWriter(輸出普通流)-----------
構(gòu)造:
FileWriter(String fileName); 傳入一個文件的路徑
方法:
void write(int c)? 寫入一個字符,int類型傳入
void write(String str) 寫入一個字符串
void write(String str, int startIndex, int len) 寫入字符串的一部分
void write(char[] cbuf) 寫入一個字符數(shù)組
void write(char[] cbuf, int startIndex, int len)寫入字符數(shù)組的一部分
void flush()? 將內(nèi)存中的數(shù)據(jù)刷新到文件中
void close()? 數(shù)據(jù)刷新到文件中,關(guān)流釋放系統(tǒng)底層資源(關(guān)閉后永久關(guān)閉,直到下次程序運行)
---------BufferedWriter(輸出緩沖流)-----------
構(gòu)造:
BufferedWriter(new FileWriter(String fileName));傳入一個FileWriter對象,FileWriter包含一個文件的路徑
方法 (同F(xiàn)ileWriter,多了一個方法):
void newLine()? 寫入換行(\r\n)
---------FileReader(輸入普通流)-----------
構(gòu)造:
FileReader(String fileName); 傳入一個文件的路徑
方法:
int read()? 讀取單個字符,若是讀取成功返回參數(shù)的int類型表現(xiàn)形式,若讀取失敗,返回-1
int read(char[] cbuf)? 讀取指定char數(shù)組長度個字符,并存入char數(shù)組,若是讀到文件尾部,則停止讀取,并返回讀取字符的個數(shù)(不是char數(shù)組長度),若是一個都沒讀到,返回-1。
int read(char[] cbuf, int startIndex, int len)? 讀取 startIndex 索引開始, len 個字符(length簡拼)
void reset() 重置流(刪除前面讀的記錄)
---------BufferedReader(輸入緩沖流)-----------
構(gòu)造:
FileReader(String fileName); 傳入一個文件的路徑
方法 (同F(xiàn)ileReader,多了一個方法)
String ReadLine()? 一次讀一行的內(nèi)容,返回讀到的內(nèi)容,沒讀到返回null
-----------Arrays(工具類,考試不推薦使用)-----------------
構(gòu)造:
不需要構(gòu)造,因為該類不需要創(chuàng)建對象
方法:
String toString(各種數(shù)組,集合不行) 返回該數(shù)組的全部內(nèi)容的特定格式(遍歷數(shù)組)
方法重載:
1.方法名相同
2.參數(shù)列表不同(數(shù)量、類型、順序)
方法覆蓋:
1.訪問修飾符相同或更寬
2.返回值類型相同
3.方法名相同
4.參數(shù)表相同
5.static 靜態(tài)只能覆蓋靜態(tài) 非靜態(tài)只能覆蓋非靜態(tài)
6.子類方法不能拋出比父類更多的異常
三大修飾符:
static
可以修飾屬性、方法和初始化代碼塊,不可以修飾局部變量
1. 靜態(tài)屬性、方法為全類所有,可通過類名直接調(diào)用
2. 靜態(tài)初始化代碼塊在類加載時執(zhí)行,僅執(zhí)行一次
final
可以修飾局部變量、成員變量、方法和類
1. final修飾的變量一旦被賦值,就不能改變
2. final修飾的方法不可以被覆蓋
3. final修飾的類不能被繼承
abstract
可以修飾類和方法
1. 抽象類只能聲明引用,不能創(chuàng)建對象
2. 抽象方法只有聲明,沒有實現(xiàn)(不寫代碼塊)
3. 如果一個類中有抽象方法,那這個類必須是抽象類
4. 子類繼承一個抽象類,如果不希望子類變成抽象類,那子類必須實現(xiàn)父類中的全部抽象方法
PS:多個修飾符修飾同一方法、類時的使用問題
1. abstract 不能與 final 一起修飾方法、類
抽象類、方法需要被繼承、覆蓋才可使用,final修飾的類、方法不可被繼承、覆蓋
2. abstract 不能與 private 一起修飾方法(private只能修飾內(nèi)部類)
理由同上,私有方法不能被繼承
3. abstract 不能與 static 一起修飾方法(static只能修飾類的成員,不能修飾類本身)
抽象類需要有子類的實現(xiàn)類才能調(diào)用內(nèi)部方法,而靜態(tài)類可以直接通過本類名調(diào)用內(nèi)部方法
4. private 與 static 與 final 可以連用(屬性、方法都可以)
權(quán)限修飾符:private default protect public 可以修飾方法
? ? public default 可以修飾類
接口:interface
1. 接口是特殊的抽象類(interface 代替了 abstract class)
2. 接口中所有屬性都是公開靜態(tài)常量
3. 接口中所有方法都是公開抽象方法
4. 一個接口可以繼承多個接口(extends 多個接口,接口之間用逗號隔開)
5. 一個類只可以繼承一個父類,但是可以實現(xiàn)多個接口
PS: 抽象類與接口的不同點
1. 抽象類可以有構(gòu)造方法,接口不可以有構(gòu)造方法
2. 抽象類不可以多繼承,接口可以多繼承
接口的實現(xiàn)(被子類繼承):implements
1. 一個類實現(xiàn)接口,如果不希望作為抽象類,就必須實現(xiàn)接口中全部方法
接口的作用;
1. 接口與多繼承
1. 可以讓子類繼承主要類型,讓次要類型作為一個接口讓子類實現(xiàn).
2. 單繼承具備簡單性(相對于多繼承),使用接口實現(xiàn)的多繼承并不會破壞其簡單性
2. 接口與解耦合
接口抽象出子類中的共性,利用多態(tài)來解耦合
3. 接口回調(diào)
實現(xiàn)某些接口,由函數(shù)庫中方法自動調(diào)用。
例:
定義實體類是實現(xiàn)Comrparable<E>接口(中的comepareTo方法,返回值為int)
在調(diào)用java.util.Arrays.sort數(shù)組排序方法時,可以排序存放實體類的數(shù)組
Object類:
Object是所有類的父類,如果一個類沒有定義直接繼承的父類,就會直接繼承Object類(自動加上extends Object)
所有的類都會繼承Object類中的全部公開方法。
Obeject類中的全部方法:
1. finalize
該方法在垃圾回收時,被垃圾回收器調(diào)用
(什么是垃圾? -- 沒有引用指向的對象)
1. JVM中有自動垃圾回收機制,程序員只需要創(chuàng)建對象、分配空間,不需要回收垃圾
2. JVM只有在內(nèi)存不夠用的時候才會進行垃圾回收
(可能會浪費空間,但減少了垃圾回收對CPU的占用)
2. getClass
作用:得到對象的"實際"類型
補充:instanceof 可看做是不是:? 引用 instanceof 類型
該引用的實際類型 是不是 某類型
比較兩個對象的實際類型是不是相等:
1. 使用 instanceof 只能得出某對象的實際樂行是不是某類型的子類
2. 可以使用getClass得到 對象的實際類型
語法:m1.getClass() == m2.getClass()
3. equals
作用: 比較兩個對象
1. 可以在子類中覆蓋equals方法,作用為使兩個對象可以使用自定義的標準相互比較
2. 如果不覆蓋equals方法,默認比較兩個對象的地址值(即使用 == 比較兩個引用類型)
3. 字符串類覆蓋了equals方法
覆蓋equals方法的五個步驟:
1. 判斷 this == obj (地址相同直接返回true)
2. 判斷 obj == null (this一定不是null,否則無法調(diào)用equals方法)
3. 判斷 兩個對象的實際類型是否相同(使用getClass方法)
4. 強制類型轉(zhuǎn)換
5. 依次比較兩個對象的屬性是否相等
4. toString
作用:打印
在控制臺打印對象時,自動調(diào)用該對象的toString方法
包裝類:
將基本數(shù)據(jù)類型封裝為對象數(shù)據(jù)類型:
int -- Integer
char -- Character
其他基本數(shù)據(jù)類型 -- 首字母大寫
int Integer String 之間的相互轉(zhuǎn)換:
1. Integer ii = new Integer( int i )
? Integer ii = new Integer( String s )
2. int i = ii.intValue()
? int i = Integer.paresInt( String s )
3. String s = ii.toString()
? String s = String.valueOf( int i )
正則表達式:
作用: 使用正則表達式可以匹配出想要的字符串
1. [] [a-zA-Z0-9] [1235] 中括號可以匹配多個字符,或者范圍內(nèi)字符,范圍使用-分隔,多組范圍直接連著寫
2. {} {5} {5,10} 限制前一個字符內(nèi)容長度,或者長度范圍,范圍使用逗號分隔
3. 特殊意義字符: \:轉(zhuǎn)義字符,想要使用\ 需要使用轉(zhuǎn)義字符 \\
? +:放在字符后面,代表匹配一個或多個該字符,想要使用+,需要使用轉(zhuǎn)義字符 \\+
? .:匹配任意一個字符,使用字符本身,需要轉(zhuǎn)義 \\.
? \\d 匹配任意字母
? \\w 匹配任意字母或者數(shù)字
? ( | ) 邏輯或,匹配 | 前面或者后面的字符,例:(J|j)ava? 可以匹配 Java 或者 java
? ^: 代表必須是字符串的開頭,例:^[a-z]? 字符串必須以小寫字母開頭
? $: 代表前一個字符必須是匹配內(nèi)容的結(jié)尾,例:^[a-z][0-9]$ 字符串必須以數(shù)字結(jié)尾
? \\_ 下劃線
內(nèi)部類:
成員內(nèi)部類:
1. 成員內(nèi)部類可以訪問外部類中所有的、靜態(tài)的、私有的屬性和方法
2. 成員內(nèi)部類中不可以定義靜態(tài)的屬性和方法
3. 創(chuàng)建成員內(nèi)部類對象,需要先創(chuàng)建一個外部類對象(依賴于獨立的外部類對象,因此不可以有靜態(tài)成員)
創(chuàng)建成員內(nèi)部類對象:
外部類 out = new 外部類();
外部類.內(nèi)部類 引用名 = out.new 外部類.內(nèi)部類();
(類型是 外部類.內(nèi)部類,作為一個外部類的成員,需要用一個外部類對象來創(chuàng)建)
靜態(tài)內(nèi)部類:
1. 靜態(tài)內(nèi)部類只能訪問外部類中所有的靜態(tài)屬性和方法
2. 靜態(tài)內(nèi)部類可以定義普通的和靜態(tài)的屬性和方法
3. 創(chuàng)建靜態(tài)內(nèi)部類對象,可以直接使用該類的類型創(chuàng)建(靜態(tài)成員不依賴于外部類的對象)
創(chuàng)建靜態(tài)內(nèi)部類對象:
外部類.靜態(tài)內(nèi)部類 引用名 = new 外部類.靜態(tài)內(nèi)部類();
(不依賴外部類對象,直接用類型創(chuàng)建)
局部內(nèi)部類:
作用同下
匿名內(nèi)部類:
new 接口名() { 接口的實現(xiàn)代碼 }
用途:
需要一個僅僅使用一次的對象時,直接在方法內(nèi)部創(chuàng)建、使用,不需要打斷思路,另開一個實現(xiàn)類
缺點:
代碼可讀性差
集合框架:
為什么使用集合: 數(shù)組的擴容、插入、刪除操作十分繁瑣
集合的類型:
Collection<Object>? 接口
-->? List<Object>? 接口
-->? Set<Object>? 接口
Map<Key, Value>? ? 接口
集合中的方法:
Collecion :
add (Object obj) -- boolean 添加元素
contains (Object obj)? -- boolean 查看是否包含某元素
isEmpty() -- boolean 集合是否為空
remove (Object obj) -- boolean 刪除某元素
clear() -- void 清空集合
size() -- int 查看集合中元素個數(shù)
List :? 元素是對象類型,元素有下標(有順序),元素可以重復(fù)
add (Object obj) / add (int index, Object obj)
添加元素,可以直接添加,或者插入到指定的index
get (int index)? set (int index, Object obj)
根據(jù)下標,獲取或者修改元素
indexOf (Object obj) -- int
獲取元素下標
Set: 元素是對象類型,元素沒有下標(沒有順序),元素不可以重復(fù)
Set集合沒有自己特有的方法,全部方法繼承自Collection
Map: 元素是鍵值對類型,鍵不可以重復(fù),值可以重復(fù)
get (Object key) -- Object
根據(jù)鍵,獲取對應(yīng)的值
put (Object key, Object value) -- void
添加一個鍵值對
remove (Object key) -- void
刪除一個鍵值對,根據(jù)值
ketSet() -- Set
獲取全部的鍵,放到一個Set里面返回
values() -- Collection
獲取全部的值,放到一個Collection中返回
containsKey/containsValus
查看Map中是否包含某個Key/Values
size()
查看Map中鍵值對個數(shù)
isEmpty()
clear()
entrySet()
獲取全部的鍵值對(Map.Entry類型),放到Set中返回
集合的實現(xiàn)類:
List 的實現(xiàn)類:
ArrayList?
1. 使用數(shù)組實現(xiàn)
2. 增刪慢,查詢快
LinkedList
1. 使用鏈表實現(xiàn)
2. 增刪快,查詢慢
Vector
1. JDK1.0遺留的產(chǎn)物
2. 重量級,線程安全,速度慢(多線程訪問同一對象時,不會出現(xiàn)同步問題)
Set 的實現(xiàn)類:
HashSet
1. 集合中的元素無序,不重復(fù)(可以用來去除一組元素中重復(fù)的數(shù)據(jù))
2. new HashSet() 默認容量16,加載因子0.75
3. newHashSet(int 容量, float )
LinkedHashSet
1. 遍歷時可以保留添加到集合中的順序(Set集合中的元素是無序的)
Set 集合是如何實現(xiàn)不重復(fù)元素的?
添加進Set集合中的元素要想做到不重復(fù)需要:
1. 需要覆蓋 equals() 方法 -- 變成比較元素內(nèi)容而不是比較元素地址
2. 需要覆蓋 hashCode() 方法 -- 使哈希碼與元素內(nèi)容有關(guān),
保證相同元素有相同哈希碼,
盡量保證不同元素哈希碼不同,
可節(jié)省運算、比較次數(shù)
如何實現(xiàn)元素不重復(fù)的?
1. 每個對象都有自己的 hashCode(hashSet使用數(shù)組加鏈表實現(xiàn))
-- hashCode決定對象在集合中的存放位置,
? 初始hashCode值由對象地址決定
2. 如果兩個對象的hashCode相同,就使用 equals() 方法進行比較,
? 去掉重復(fù)元素,不重復(fù)的掛到該hashCode對應(yīng)數(shù)組位置中的鏈表里
3. 如果兩個對象hashCode不同,那么放入集合的位置就可能不同,
? 兩個對象就不會進行 equals() 方法比較的過程,因此必須修改hashCode方法
? 讓內(nèi)容可能相同的對象hashCode相同,進行比較去重復(fù)。
? 同時也要盡量保證內(nèi)容不同的對象的hashCode不同,盡量加快運算速度。
equals方法:
1. 判斷兩個對象地址是否相同(直接等于)
2. 判斷參數(shù)對象是否為空
3. 判斷兩個對象類型是否相同(使用getClass方法)
使用 instanceof 有可能遇到父子類的情況
4. 將參數(shù)對象類型強轉(zhuǎn)成本類對象類型
5. 逐個比較兩個對象的屬性
Map 的實現(xiàn)類:
HashMap
1. 鍵不可以重復(fù),同樣需要覆蓋 equals 方法和 hashCode 方法
2. 允許鍵/值為 null
LinkedHashMap
1. 遍歷時,保留了鍵的放入順序
HashTable
1. 類似于 Vector ,重量級,速度慢,線程安全
2. 當鍵/值為 null 時,會拋出異常
Map 集合的三種遍歷方式:
鍵遍歷:
使用 keySet() 方法,拿到全部鍵的Set,再遍歷 Set 即可(配合 get(key) 方法拿值)
值遍歷:
使用 values() 方法,拿到全部值的Collection
鍵值對遍歷:
1.使用 entrySet() 方法,拿到全部的鍵值對Set
裝有鍵值對的Set的泛型需要注意寫法:
例: Set<Map.Entry<Integer, String>> set = map.entrySet();
鍵值對的類型為:Map.Entry , 例: Map.Entry entry? = (Map.Entry)iter.next();
鍵值對的迭代器遍歷時,需要將從Set中取出
的值強轉(zhuǎn)成 Map.Entry 類型
↑↑以上是JDK5.0之前泛型沒出的時候的做法
加泛型之后,不需要在強轉(zhuǎn)了
2. 使用Map.Entry類中的 getKey() / getValue() 方法,獲取鍵值對中的鍵和值
PS:用迭代器遍歷集合
Iterator iter = list.iterator(); --> List 和 Set 中有iterator方法,獲取迭代器
//創(chuàng)建一個迭代器對象
while( iter.hasNext() ) {
Object value = iter.next();
//對拿到的value進行需要的操作
}
foreach遍歷
1. foreach封裝了迭代器遍歷
2. 迭代器對與集合長度及變化做了安全監(jiān)測,
3. 定義了異常:ConcurrentModificationException 并發(fā)修改異常
4. 在使集合創(chuàng)建迭代器時,會為變量expectedModCount賦值(賦予當前modCount的值)
5. foreach遍歷集合時,先調(diào)用hasNext方法,指針后移,如果索引等于集合長度,
則結(jié)束循環(huán),如果索引小于集合長度,
則通過next()取出指針指向的集合內(nèi)對象地址,執(zhí)行循環(huán)體。
6. 在next()中進行集合長度及變化的安全監(jiān)測,如果索引大于集合長度,則說明在
上一次循環(huán)的循環(huán)體中,出現(xiàn)了修改集合長度的操作,則直接拋出
并發(fā)修改異常;集合之中有一個成員變量modCount,
記錄了集合被增刪元素的次數(shù),next()中會先比較expectedModCount和
modCount的值是否相同,及監(jiān)測集合有沒有被修改過,如果不同就拋出
并發(fā)修改異常
PS: 7. 安全監(jiān)測是在next方法中進行的,因此若是刪除集合的倒數(shù)第二個元素:
在循環(huán)體執(zhí)行刪除語句,刪除后集合長度-1,循環(huán)體結(jié)束進入下一次循環(huán)判斷
hasNext方法:索引長度剛好等于集合長度,結(jié)束循環(huán),不進入next方法。
所以:可以在foreach遍歷集合中,刪除倒數(shù)第二個元素。
? ? 8. iterator的remove方法對集合修改安全監(jiān)測進行了屏蔽處理,
使用iterator中的方法刪除元素,不會拋出異常
結(jié)論:Iterator做出了安全監(jiān)測,集合對象不可以在foreach循環(huán)遍歷集合中,
做出增加刪除元素的操作,否則拋出并發(fā)修改異常。
(除了刪除倒數(shù)第二個元素)
集合工具類:
Collections :(靜態(tài)方法)
1. Collections.shuffle(list) 打亂一個List集合中元素的排列順序
2. Collections.sort(list) 按照自然順序排序一個List集合內(nèi)的元素
3. Collections 只能作用于List集合
Properties:持久的屬性集
1. Properties繼承自Map集合
2. Properties中有方法可以將集合中內(nèi)容保存在文本文件中
3. Properties限定泛型,只能裝String類型數(shù)據(jù)(name,value)
4. Properties中的常用方法:
1. setProperties(String, String)
2. getProperties(String key)
3. stringPropertyNames(獲取集合中全部的name的 Set 集合)
4. store(OutputStream,String comments) -- 將集合中數(shù)據(jù)通過輸出流保存在文本文件中
自定義一個輸出流,文本文件必須以.properties結(jié)尾,commetns為注釋,可以為null
5. load(InputStream) -- 通過一個輸入流將文件中內(nèi)容傳入Properties對象中