目錄
一,常用類庫
1,泛型
1.1 概述
1.2 使用
1.3 執行個體
1.4 限制泛型類型
1.5 泛型中的通配符
2,java.util.Objects
2.1 Object與Objects
2.2 Objects中的equals
2.3 Objects中的requireNonNull
3,java.lang.Math
4,java.util.Arrays
4.1 二分查找binarySearch
4.2 比較兩個數組compare
4.3 複制數組copyOf、copyOfRange
4.4 判斷數組是否相等equals
4.5 填充數組fill
4.6 數組排序sort、parallelSort
4.7 數組轉換為字元串形式toString
5,java.math.BigDecimal
5.1 問題引入
5.2 常用方法及使用
6,java.util.Date
6.1 概念
6.2 應用
7,java.text.DateFormat
7.1 概念
7.2 應用
8,java.util.Calendar
8.1 對象建立過程源碼解析
8.2 如何擷取年月日時分秒:get(不能通過getDay之類的方法直接得到)
8.3 如何獲得今天是一年中的第幾天:get
8.4 如何設定月曆來友善計算:set
8.5 通過加減修改年月日等參數:add
8.6 将Calendar對象轉換為Date對象:getTime
8.7 獲得字段的最大值:getActualMaxmum
9,String
9.1 為什麼字元串類型無法更改長度
9.3 String對象可共享
9.4 字元串常量池
9.5 被雙引号包含的都是字元串對象
9.6 其他常用的字元串構造方法(最常用的還是直接指派)
9.7 常用的字元串方法
9.8 字元串拼接中的問題
一,常用類庫
1,泛型
1.1 概述
1,泛型,即“參數化類型”。就是将類型由原來的具體的類型參數化,類似于方法中的變量參數,此時類型也定 義成參數形式(可以稱之為類型形參),然後在使用/調用時傳入具體的類型(類型實參)。
2,注意
在編譯之後程式會采取去泛型化的措施。
3,作用
- 也就是說Java中的泛型,隻在編譯階段有效。
- 在編譯過程中,正确檢驗泛型結果後,會将泛型的相關資訊擦出,并且在對象進入和離開方法的邊界處添加 類型檢查和類型轉換的方法。也就是說,泛型資訊不會進入到運作時階段
- 1、 提高代碼複用率
- 2、 泛型中的類型在使用時指定,不需要強制類型轉換(類型安全,編譯器會檢查類型)
1.2 使用
1,泛型類
public class ClassName<T>{
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
2,泛型接口
public interface IntercaceName<T>{
T getData();
}
實作接口時,可以選擇指定泛型類型,也可以選擇不指定, 如下:
指定類型:
public class Interface1 implements IntercaceName<String> {
private String text;
@Override
public String getData() {
return text;
}
}
不指定類型:
public class Interface1<T> implements IntercaceName<T> {
private T data;
@Override
public T getData() {
return data;
}
}
3, 泛型方法
方法的類型是泛型,傳回值也是泛型
private static <T> T 方法名(T a, T b) {}
另一個例子
1.3 執行個體
1,假設在定義時不确定類型,但使用時可以确定: 2,測試方法
1.4 限制泛型類型
在使用泛型時, 可以指定泛型的限定區域 ,
- 例如: 必須是某某類的子類或 某某接口的實作類,格式:
<T extends 類或接口1 & 接口2>
1.5 泛型中的通配符
類型通配符是使用?代替方法具體的類型實參。上界限定(限定父類) 下界确定
- 1 <? extends Parent> 指定了泛型類型的上屆
- 2 <? super Child> 指定了泛型類型的下屆
- 3 <?> 指定了沒有限制的泛型類型
2,java.util.Objects
2.1 Object與Objects
1,Object 2,Objects
2.2 Objects中的equals
1,使用對象的equals方法 2,使用Objects中的equals方法 3,源碼
2.3 Objects中的requireNonNull
判斷對象是否為空,若為空則抛出異常 。常用于要求對象不能為空的場景:
3,java.lang.Math
4,java.util.Arrays
4.1 二分查找binarySearch
1,相關API 2,應用
4.2 比較兩個數組compare
4.3 複制數組copyOf、copyOfRange
1,相關API 2,應用
4.4 判斷數組是否相等equals
4.5 填充數組fill
4.6 數組排序sort、parallelSort
1,相關API 2,應用
4.7 數組轉換為字元串形式toString
1,相關部分API 2,應用 3,源碼
5,java.math.BigDecimal
5.1 問題引入
1,輸出兩個小數之和通過在控制台運作0.1+0.2。 會發現float和double的運算誤差
由于float類型和doub1 e類型在運算時可能會有誤差,為了實作精确運算則需要借助java.math. BigDecima 類加以描述
5.2 常用方法及使用
1,需要通過BigDecimal建立對象,相要參與運算的小數的字元串形式作為參數。
2,常用方法
3,轉換為特定類型
6,java.util.Date
6.1 概念
在JDK 1.1之前, Date類還有兩個附加功能。 它允許将日期解釋為年,月,日,小時,分鐘和秒值。 它還允許格式化和解析日期字元串。 不幸的是,這些功能的API不适合國際化。 從JDK 1.1開始, Calendar類應該用于在日期和時間字段之間進行轉換,而DateFormat類應該用于格式化和解析日期字元串。 不推薦使用Date中的相應方法。目前常用的方法:
1,目前時間
2,指定時間 3,擷取時間戳
6.2 應用
1,列印目前時間 2,列印提前一小時的時間
7,java.text.DateFormat
7.1 概念
用于格式化和解析字元串。DateFormat是一個抽象類,經常使用他的直接子類SimpleDateFormat
7.2 應用
1, 格式定義。将時間轉換為指定格式 2,使用方法format轉換為想要的格式 3,使用方法parse 将指定格式的時間字元串轉換為date對象 4,計算時間差
8,java.util.Calendar
可以解決國際化的問題。Calendar為抽象類,需要通過getInstance獲得對象;
8.1 對象建立過程源碼解析
1,建立calendar對象,進入Calendar類,找到getInstance方法 2,再次進入createCalendar方法 3,可以看到标準化操作,不同地區的建立方法
8.2 如何擷取年月日時分秒:get(不能通過getDay之類的方法直接得到)
1,找到Calendar類中的fields數組,存放年月日時分秒相關的資訊 2,這些常量表示相應字段在數組中的下标 3,實際使用運作效果 4,調用過程:get-》internalGet
8.3 如何獲得今天是一年中的第幾天:get
1,使用get方法,并傳入相應參數 2,運作效果
8.4 如何設定月曆來友善計算:set
1,使用set方法
8.5 通過加減修改年月日等參數:add
1,增加年份add2,增加月份
注意國外月份0-11表示1-12.此外國外的星期日表示一周的開始
8.6 将Calendar對象轉換為Date對象:getTime
8.7 獲得字段的最大值:getActualMaxmum
9,String
String類表示字元串。 Java程式中的所有字元串文字(例如"abc" )都實作為此類的執行個體。
- 字元串是不變的; 它們的值在建立後無法更改。
- 字元串緩沖區支援可變字元串。
- 因為String對象是不可變的,是以可以共享它們。(如果兩字元串内容完全相同,則采用同一塊記憶體位址)
之前的操作中,可以發現,使用String可以表示出一個字元串,但是使用此類的時候也會發現有一點的問題。
從String命名風格可以發現,String 是一一個類, 但是此類在使用的時候卻發現可以不用構造方法而直接指派,那麼這樣操作有那些特點呢?
9.1 為什麼字元串類型無法更改長度
數組的長度無法更改
9.3 String對象可共享
如果兩字元串内容完全相同,則采用同一塊記憶體位址(前提是不通過new實作,隻要使用了new就一定會開辟兩個不同的記憶體空間)
9.4 字元串常量池
1,方法區
方法區(Method Area),又稱永久代(Permanent Generation)(永久存儲在記憶體中,就像靜态代碼塊不會執行兩次一樣), 又稱非堆區( Non-Heap space)方法區,又稱永久代(Permanent Generation) ,常稱為PermGen,位于非堆空間,又稱非堆區(Non-Heap space)。
方法區是被所有線程共享。
- 所有字段和方法位元組碼,以及一些特殊方法如構造函數,接口代碼也在此定義。
- 簡單說,所有定義的方法的資訊都儲存在該區域,此區屬于共享區間。
- 這些區域存儲的是:靜态變量 +常量+類資訊(構造方法/接口定義) +運作時常量池。
但是,執行個體變量 存在堆記憶體中,和方法區無關。
以上,隻是邏輯上的定義。在HotSpot中,方法區僅僅隻是邏輯上的獨立,實際上還是包含在Java堆中,也是就說,方式區在實體上屬于Java堆區中的一部分,而永久區(Permanent Generation) 就是方法區的實作。
2、堆(heap)
一個JW執行個體隻存在一一個堆記憶體,堆記憶體的大小是可以調節的。類加載器讀取了類檔案後,需要把類、方法、常變量放到堆内
存中,儲存所有引用類型的真實資訊,以友善執行器執行。
堆在邏輯上分為三部分(Perm) :
- 新生代(Young Generation, 常稱為YoungGen)
- 老年代(01d Generation, 常稱為oldGen、TenuringGen)
- 永久代(Permanent Generation, 常稱為PermGen)
2.1、新生區(New/Young Generation)
新建立的對象都在新生代,在15次GC回收中被回收,就是新生代
- 新生代(Young Generation) ,常稱為YoungGen,位于堆空間;
- 新生區又分為Eden區和Survior (幸存區)。
Eden :新建立的對象
Survior 0、1:經過垃圾回收,但是垃圾回收次數小于15次的對象
2.2、養老代(01d Generation)
- 老年代(old Generation) ,常稱為oldGen,位于堆空間;
- old :垃圾回收次數超過15次,依然存活的對象
2.3、永久區(Permanent Generat ion)
字元串都存在于永久代,是以兩個内容相同的字元串引用會指向同一位址(除了new出來的String,因為new一定會開辟新的記憶體空間)
永久代(Permanent Generation) , 常稱為PermGen, 位于非堆空間。
永久區是一個常駐記憶體區域,用于存放JDK自身所攜帶的Class , Interface的中繼資料,也就是說它存儲的是運作環境必須的類資訊,被裝載進此區域的資料是不會被垃圾回收器回收掉的,關閉JVM才會釋放此區域所占用的記憶體。
2.3.1、方法區的實作的演變:
- Jdk1.7之前: hotspot虛拟機對方法區的實作為永久代;
- Jdk1. 8及之後: hotspot移除了永久代用元空間(Metaspace),
2.3.2、運作時常量池存和字元串常量池的變化
JDK1.7之前:
JDK1.7 :
- 運作時常量池(包含字元串常量池)存放在方法區,此時hotspot虛拟機對方法區的實作為永久代。
JDK1.8 :
- 字元串常量池被從方法區拿到了堆中;
- 運作時常量池剩下的東西還在方法區,也就是hotspot中的永久代。
- hotspot移除了永久代,用元空間(Metaspace)取而代之。這時候,
- 字元串常量池還在堆,
- 運作時常量池還在方法區,隻不過方法區的實作從永久代變成元空間(Metaspace)。
9.5 被雙引号包含的都是字元串對象
隻要是被雙引号包住的都是字元串對象,如果沒有賦予名稱的話,屬于匿名對象
9.6 其他常用的字元串構造方法(最常用的還是直接指派)
9.7 常用的字元串方法
9.8 字元串拼接中的問題
1,先聲明三個字元串對象 text1,text2,text3 2,将三個字元串對象連接配接後新位址存放在text1中 3,造成的結果4,實際應用場景中的副作用
爬蟲時,把爬取到的字元串全都拼接起來,很快就會發現記憶體不夠用,因為有很多垃圾在裡面(拼接一次産生一次垃圾)。是以拼接字元串,能少做盡量少做,尤其是通過+号拼接;
5,如何拼接大量的字元串?
找到String實作的父類接口CharSequence。可以看到其的兩個子類:StringBuffer,StringBuilder。
6,拼接方法
首先通過無參方式建立空的StringBuffer/StringBuilder;
其次通過append方式,進行添加,容量不夠就根據動态擴容算法進行擴容。重點是不會在緩沖區存儲,通過+号連接配接,因為是在常量緩沖池中存儲,是以不會被回收;
7,将結果轉換為String
8,雖然麻煩但是節省記憶體,是以對字元串操作時,推薦使用此方法