java核心技術(shù)第六篇之斷言、日志、包裝類型和工具類

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對象中

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、基礎(chǔ)知識:1、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機...
    殺小賊閱讀 2,576評論 0 4
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 3,179評論 2 9
  • 四、集合框架 1:String類:字符串(重點) (1)多個字符組成的一個序列,叫字符串。生活中很多數(shù)據(jù)的描述都采...
    佘大將軍閱讀 879評論 0 2
  • 面向?qū)ο笾饕槍γ嫦蜻^程。 面向過程的基本單元是函數(shù)。 什么是對象:EVERYTHING IS OBJECT(萬物...
    sinpi閱讀 1,228評論 0 4
  • 1.import static是Java 5增加的功能,就是將Import類中的靜態(tài)方法,可以作為本類的靜態(tài)方法來...
    XLsn0w閱讀 1,443評論 0 2

友情鏈接更多精彩內(nèi)容