JavaSE——常用类库(上)(泛型、Objects、Math、ArraysBigDecimal类)
第1節(jié) 常用類庫(上)
面向?qū)ο蟾嗍撬枷肷系臇|西,常用類庫更多是工具上的東西,熟能生巧,多整理筆記。
一、泛型
1.1 概述
泛型,即“參數(shù)化類型”。就是將類型由原來具體類型進(jìn)行參數(shù)化 ,類似于方法中的變量參數(shù),此時(shí)類型也定義成參數(shù)形式(可以稱之為類型形參 ),然后在使用/調(diào)用時(shí)傳入具體的類型(類型實(shí)參) 。
1.2 泛型的使用
泛型一般在類、接口和方法中使用,其中主要是類中用的更多。1.2.1 泛型在類中的使用
先來看定義的時(shí)候的格式: package com.kaikeba.coreclasslibrary;public class Person<A> {private String name;private int age;//這里是形參,實(shí)際使用該類時(shí)需要給定實(shí)參,在該類中可以用A來代替一種不確定的類型private A data;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public A getData() {return data;}public void setData(A data) {this.data = data;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", data=" + data +'}';} } 再看使用時(shí)的格式: package com.kaikeba.coreclasslibrary;public class genericParadigm {public static void main(String[] args) {//實(shí)際使用時(shí)指定具體的類型給泛型,那么該類中所有的A全部替換為IntegerPerson<Integer> p = new Person<>();} }看下面?zhèn)魅氩煌念愋?#xff0c;setData方法的參數(shù)列表中data的類型也隨之變化:
1.2.2 泛型在接口中的使用
定義時(shí)格式如下所示,和類中基本一致: public interface 接口名<T> {T getData(); }接口都是要被類實(shí)現(xiàn)才有意義,實(shí)現(xiàn)接口時(shí),可以選擇指定泛型類型,也可以選擇不指定,如下所示:
1、指定類型
//指定類型:這樣的類使用時(shí)無需再給泛型具體的類型,直接使用即可 public class 類名 implements 接口名<String> {private String text;@Overridepublic String getData() {return text;} }具體的使用案例:
package com.kaikeba.coreclasslibrary;public class genericParadigm2 {public static void main(String[] args) {Apple a = new Apple();a.text = "123";System.out.println(a.getData());}}interface Fruit<T>{T getData(); }//實(shí)現(xiàn)接口時(shí)指定類型 class Apple implements Fruit<String>{String text;@Overridepublic String getData() {return text;} }結(jié)果為:1232、不指定類型:
//不指定類型:使用類時(shí)需要給定具體的類型 public class 類名<T> implements 接口名<T> {private T text;@Overridepublic T getData() {return text;} }具體的使用案例:
package com.kaikeba.coreclasslibrary;public class genericParadigm2 {public static void main(String[] args) {Apple<String> a = new Apple<>();a.text = "123";System.out.println(a.getData());}}interface Fruit<T>{T getData(); }//實(shí)現(xiàn)接口時(shí)不指定類型 class Apple<T> implements Fruit<T>{T text;@Overridepublic T getData() {return text;} }結(jié)果:1231.2.3 泛型在方法中的使用
泛型方法的格式如下,注意位置與類和接口不一樣: private static <T> T 方法名(T a, T b) {} 想用T的地方可以用T,不想用的地方就用自己想用的類型即可,上述的格式案例中全用了T,下面看個(gè)例子: package com.kaikeba.coreclasslibrary;public class genericParadigm {public static void main(String[] args) {//根據(jù)傳入的實(shí)際參數(shù)類型,自動獲取泛型的類型print(123);}public static <A> void print(A a) {System.out.println(a);} }結(jié)果:1231.3 泛型限制類型
在使用泛型的時(shí)候,可以指定泛型的限定區(qū)域,例如:必須是某某類的子類 或 某某接口的實(shí)現(xiàn)類,格式:
<T extends 類或接口1 & 接口2>注意:這里不論是類還是接口,都是使用extends關(guān)鍵字。
package com.kaikeba.coreclasslibrary;public class genericParadigm2 {public static void main(String[] args) {// 如果傳入的不是水果的實(shí)現(xiàn)類,會報(bào)錯(cuò)// Plate<String> p = new Plate<>();// p.data = "String";// 如果傳入的符合要求,則正確Plate<Apple> p = new Plate<>();} }//定義一個(gè)水果接口 interface Fruit<T>{T getData(); }//實(shí)現(xiàn)水果接口的蘋果類 class Apple<T> implements Fruit<T>{T text;@Overridepublic T getData() {return text;} }//泛型限制只能傳入水果接口的實(shí)現(xiàn)類 class Plate<T extends Fruit>{T data; }1.4 泛型中的通配符——?
類型通配符是使用 ? 代替方法具體的類型實(shí)參。
<? extends Parent>指定了泛型類型的上界,必須是Parent或其子類;
<? super Child>指定了泛型類型的下界,必須是Child或其父類;
<?>指定了沒有限制的泛型類型。
1.5 泛型的作用以及注意事項(xiàng)
作用:
提高代碼的復(fù)用率
泛型中的類型在使用時(shí)指定,不需要強(qiáng)制類型轉(zhuǎn)換(類型安全,編譯器會檢查類型)
注意事項(xiàng):
在編譯之后程序會采取去泛型化的措施,也就是Java中的泛型,只在編譯階段有效。在編譯過程中,正確檢驗(yàn)泛型結(jié)果后,會將泛型的相關(guān)信息擦除,并且在對象進(jìn)入和離開方法的邊界處添加類型檢查和類型轉(zhuǎn)換的方法,也就是說,泛型信息不會進(jìn)入到運(yùn)行時(shí)階段。
二、java.util.Objects類
Objects類以及下面介紹的每一種類庫,最好的學(xué)習(xí)方法就是看源碼以及注釋,其次可以配合中文手冊,下面就是對其的整理。
簡介: 此類由靜態(tài)實(shí)用程序方法組成,用于對對象進(jìn)行操作,或在操作前檢查某些條件。這些實(shí)用程序包括空安全 (null-safe) 或空容忍 (null-tolerant) 方法,用于計(jì)算對象的哈希代碼、返回對象的字符串、比較兩個(gè)對象以及檢查索引或子范圍值是否超出范圍等等。
2.1 checkFromIndexSize
2.2 checkFromToIndex
2.3 checkIndex
上面這三個(gè)判斷索引范圍,自己寫也很簡單。。。
2.4 compare
注意不是返回o,是返回0,還是看源碼注釋比較靠譜。。。
2.5 deepEquals
這個(gè)暫時(shí)用不到,用到了再來補(bǔ)充筆記。
2.6 euqals
這個(gè)目前比較重要,翻譯的實(shí)在不太行,以后還是多看源碼吧。
它的作用在于,如果一個(gè)對象為null,那么它調(diào)用默認(rèn)Object的equals方法,會報(bào)空指針異常:
package com.kaikeba.coreclasslibrary.objects;import java.util.Objects;/*** Objects*/ public class Demo {public static void main(String[] args) {String s1 = null;String s2 = "456";System.out.println(s1.equals(s2));} }結(jié)果為: Exception in thread "main" java.lang.NullPointerExceptionat com.kaikeba.coreclasslibrary.objects.Demo.main(Demo.java:12)因?yàn)閚ull對象沒有equals方法。
但是如果使用Objects.equals則不會:
package com.kaikeba.coreclasslibrary.objects;import java.util.Objects;/*** Objects*/ public class Demo {public static void main(String[] args) {Person p1 = null;Person p2 = new Person();System.out.println(Objects.equals(p1, p2));} }結(jié)果為: false看一下equals的源碼就知道了:
public static boolean equals(Object a, Object b) {return (a == b) || (a != null && a.equals(b)); }首先判斷a和b是否指向同一個(gè)對象,是則返回true,不是則看右邊的括號,如果a為null,直接返回false,不空才調(diào)用Object.equals方法進(jìn)行比較,這樣可以避免因?yàn)榭諏ο髮?dǎo)致的異常拋出。
2.7 hash
哈希值目前還沒介紹,后續(xù)補(bǔ)充。。。
2.8 hashCode
返回一個(gè)非空對象的哈希碼,空對象返回0。
源碼如下:
public static int hashCode(Object o) {return o != null ? o.hashCode() : 0; }2.9 isNull,nonNull
public static boolean isNull(Object obj) {return obj == null; } public static boolean nonNull(Object obj) {return obj != null; }2.10 requireNonNull、requireNonNullElse、requireNonNullElseGet
2.11 toString
三、java.lang.Math
Math類包含用于執(zhí)行基本數(shù)值運(yùn)算的方法,如初等指數(shù)、對數(shù)、平方根和三角函數(shù)。
看幾個(gè)較常用的:
package com.kaikeba.coreclasslibrary.math;/*** Math*/ public class Demo {public static void main(String[] args) {System.out.println(Math.abs(-100));System.out.println(Math.min(100, 200));//返回最接近的整數(shù)System.out.println(Math.round(100.55));System.out.println(Math.round(-100.55));//返回小于等于參數(shù)的最大整數(shù)System.out.println(Math.floor(3.5));System.out.println(Math.floor(-3.5));//返回大于等于參數(shù)的最大整數(shù)System.out.println(Math.ceil(3.5));System.out.println(Math.ceil(-3.5));} }結(jié)果如下: 100 100 101 -101 3.0 -4.0 4.0 -3.0四、java.util.Arrays
該類包含用于操作數(shù)組的各種方法(例如排序和搜索)。 此類還包含一個(gè)靜態(tài)工廠,允許將數(shù)組視為列表。
如果指定的數(shù)組引用為null,則此類中的方法都拋出NullPointerException ,除非另有說明。
4.1 binarySearch
除此之外,還有各種其他類型的二分查找,都是在一個(gè)數(shù)組中查找指定的值,返回找到的索引。
4.2 compare
比較兩個(gè)數(shù)組
4.3 copyOf
將一個(gè)數(shù)組里的內(nèi)容復(fù)制到一個(gè)新的長度的數(shù)組中。
4.4 copyOfRange
將指定數(shù)組的指定范圍內(nèi)容復(fù)制到新數(shù)組中。
4.5 equals
比較兩個(gè)數(shù)組是否相同。
4.6 fill
將指定的元素分配給數(shù)組中每一個(gè)元素。
4.7 mismatch
查找并返回兩個(gè)數(shù)組中第一個(gè)不匹配的索引。
4.8 sort
按升序?qū)?shù)組進(jìn)行排序。
4.9 toString
返回?cái)?shù)組內(nèi)容的字符串表示形式。
上述的方法并沒有全部總結(jié),還有一些不常用的方法沒有整理。
下面看一個(gè)例子:
package com.kaikeba.coreclasslibrary.arrays;import java.util.Arrays;public class Demo {public static void main(String[] args) {int[] arr = {8,1,2,3,4,5,6,7};//直接輸出arr是地址信息System.out.println(arr);//下面可以輸出數(shù)組的內(nèi)容,但是很麻煩for(int i=0; i<arr.length; i++) {if(i == arr.length - 1) {System.out.print(arr[i]);}else {System.out.print(arr[i] + ", ");}}System.out.println();//Arrays中的方法都是靜態(tài)的,直接用類名調(diào)用,無需新建對象//toString方法可以直接輸出數(shù)組內(nèi)每個(gè)元素System.out.println(Arrays.toString(arr));//sort方法可以升序排序Arrays.sort(arr);System.out.println(Arrays.toString(arr));//二分查找指定元素的索引,前提:數(shù)組必須有序System.out.println(Arrays.binarySearch(arr, 6));//動態(tài)擴(kuò)容arr = Arrays.copyOf(arr, 15);System.out.println(Arrays.toString(arr));} }結(jié)果如下所示: [I@7c30a502 8, 1, 2, 3, 4, 5, 6, 7 [8, 1, 2, 3, 4, 5, 6, 7] [1, 2, 3, 4, 5, 6, 7, 8] 5 [1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0]五、java.math.BigDecimal
5.1 概念
通過在控制臺運(yùn)行0.1+0.2,會發(fā)現(xiàn)float和double的運(yùn)算誤差:
package com.kaikeba.coreclasslibrary.bigdecimal;import java.math.BigDecimal;public class Demo {public static void main(String[] args) {System.out.println(0.1+0.2);} }結(jié)果: 0.30000000000000004雖然誤差很小,但是在類似于銀行這種地方,這些小誤差累計(jì)起來還是很嚴(yán)重的,所以需要一種嚴(yán)格準(zhǔn)確的計(jì)算類。為了實(shí)現(xiàn)精確運(yùn)算就需要借助java.math.BigDecimal類對要計(jì)算的對象加以描述。
5.2 常用構(gòu)造方法
有很多構(gòu)造方法,最常用字符串來指定精確值: public BigDecimal(String val) { }如:
BigDecimal b1 = new BigDecimal("0.1"); BigDecimal b2 = new BigDecimal("0.2");5.3 常用方法
有很多關(guān)于數(shù)學(xué)運(yùn)算的方法,最常用的還是加減乘除四個(gè)。下述所有的運(yùn)算方法,不會影響參與運(yùn)算的數(shù)據(jù)本身,運(yùn)算的結(jié)果會被封裝為一個(gè)新的BigDecimal對象,這個(gè)對象會通過return返回出去。
public BigDecimal add(BigDecimal augend):加法運(yùn)算
public BigDecimal subtract(BigDecimal augend):減法運(yùn)算
public BigDecimal multiply(BigDecimal augend):乘法運(yùn)算
public BigDecimal divide(BigDecimal augend):除法運(yùn)算
看一個(gè)例子:
package com.kaikeba.coreclasslibrary.bigdecimal;import java.math.BigDecimal;public class Demo {public static void main(String[] args) {BigDecimal b1 = new BigDecimal("0.1");BigDecimal b2 = new BigDecimal("0.2");BigDecimal b3 = b1.add(b2);System.out.println(b1);System.out.println(b2);System.out.println(b3);} }結(jié)果: 0.1 0.2 0.3總結(jié)
以上是生活随笔為你收集整理的JavaSE——常用类库(上)(泛型、Objects、Math、ArraysBigDecimal类)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MATLAB如何把图片显示在GUI上
- 下一篇: Debian10降级安装php,如何在D