JAVA基本類(lèi)型包裝類(lèi) BigDecimal BigInteger 的使用
1、了解包裝類(lèi)
Java
中預(yù)定義了八種基本數(shù)據(jù)類(lèi)型,包括:byte
,int
,long
,double
,float
,boolean
,char
,short
?;绢?lèi)型與對(duì)象類(lèi)型最大的不同點(diǎn)在于,基本類(lèi)型基于數(shù)值,對(duì)象類(lèi)型基于引用。
例如有一個(gè)方法 f() ,它的參數(shù)分別是對(duì)象類(lèi)型 和 基本類(lèi)型:
void f(Object obj){ //參數(shù)引用類(lèi)型,保存的是內(nèi)存地址 } f(123){ //基本類(lèi)型 }
基本類(lèi)型基于數(shù)值,所以基本類(lèi)型是沒(méi)有類(lèi)而言的,是不存在類(lèi)的概念的,也就是說(shuō),變量只能存儲(chǔ)數(shù)值,而不具備操作數(shù)據(jù)的方法。
對(duì)象類(lèi)型則截然不同,變量實(shí)際上是某個(gè)類(lèi)的實(shí)例,可以擁有屬性方法等信息,不再單一的存儲(chǔ)數(shù)值,可以提供各種各樣對(duì)數(shù)值的操作方法,但代價(jià)就是犧牲一些性能并占用更多的內(nèi)存空間。
Java
中提供了哪些「包裝類(lèi)型」來(lái)彌補(bǔ)「基本類(lèi)型」不具備面向?qū)ο笏枷氲牧觿?shì)呢?看下圖:
java.lang.Number
這里需要提到 java.lang.Number
,它是所有數(shù)值類(lèi)的父類(lèi),其直接子類(lèi)包括:Byte
、Short
、Integer
、Long
、Float
、Double
、BigDecimal
、BigInteger
。
這些類(lèi)取出內(nèi)部封裝的基本類(lèi)型值的方法很簡(jiǎn)單也很好記:byteValue()
、shortValue()
、intValue()
、longValue()
、floatValue()
、doubleValue()
其他使用方法也基本相同,下面我們以 Integer 和 Double 為例具體講一講
2、Integer
首先需要明確一點(diǎn)的是,既然 Integer
是 int
的包裝類(lèi)型,那么必然 Integer 也能像 int 一樣存儲(chǔ)整型數(shù)值。有興趣的同學(xué)可以看看源碼。
Integer
類(lèi)的內(nèi)部定義了一個(gè)私有字段 value
,專(zhuān)門(mén)用于保存一個(gè)整型數(shù)值,整個(gè)包裝類(lèi)就是圍繞著這個(gè) value 封裝了各種不同操作的方法:
創(chuàng)建對(duì)象
Integer i1 = 21; Integer i2 = Integer.valueOf("21");
自動(dòng)拆裝箱
所謂「拆箱」就是指,包裝類(lèi)型轉(zhuǎn)換為基本類(lèi)型的過(guò)程,而所謂的「裝箱」則是基本類(lèi)型到包裝類(lèi)型的過(guò)程。
Integer integer = new Integer(21);//裝箱 int num = integer.intValue();//拆箱
自從 jdk1.5 以后,引入了自動(dòng)拆裝箱的概念,上述代碼可以簡(jiǎn)化成如下代碼:
Integer integer = 21;//裝箱 int num = integer;//拆箱
我們來(lái)進(jìn)行分析一下。
自動(dòng)裝箱
Integer integer = 21;
給一個(gè) Integer
類(lèi)型的對(duì)象不能直接賦一個(gè)基本類(lèi)型值,integer
保存的是一個(gè)內(nèi)存地址。21 自動(dòng)封裝成一個(gè)對(duì)象,把這個(gè)對(duì)象的地址賦值給 integer
。這個(gè)對(duì)象是自動(dòng)創(chuàng)建的,是自動(dòng)裝箱。在程序中編譯成:Integer integer = Integer.valueOf(21);
自動(dòng)拆箱
int num = integer
; 定義一個(gè) int 類(lèi)型變量,num 應(yīng)該直接存一個(gè)值,integer 保存的是一個(gè)內(nèi)存地址。integer 自動(dòng)取出對(duì)象中的值,然后把值賦值給 num。系統(tǒng)為我們執(zhí)行了:int num = integer.intValue();
拆裝箱是需要方法調(diào)用的,耗資源,所以我們的程序中應(yīng)當(dāng)盡量避免大量的「拆裝箱」操作。
自動(dòng)拆箱要當(dāng)心 null 值
我們看以下程序:
public class Main { public static void main(String[] args) { int j = 0; List<Integer> list = new ArrayList<>(); list.add(3); list.add(null); for (int i : list) { j += i; } System.out.println(j); } }
運(yùn)行時(shí)會(huì)報(bào)空指針
所以在獲取到值有可能為空要裝箱的時(shí)候,一定要加上 null 值的校驗(yàn)。所以可以把程序改為:
程序結(jié)果為:
3
面試題1
Integer i1 = 100; Integer i2 = 100; Integer i3 = 200; Integer i4 = 200; System.out.println(i1==i2); System.out.println(i3==i4);
輸出結(jié)果:
true
false
Integer
類(lèi)中,存在 Integer
實(shí)例緩存數(shù)組,范圍:-128 - 127。如果在自動(dòng)裝箱的時(shí)候給局部變量的int型值是在上面的范圍之中,如果是范圍內(nèi)的值,就使用存在的緩存對(duì)象;如果不是范圍內(nèi)的值,會(huì)新建對(duì)象。
面試題2
Integer i1 = new Integer(21); Integer i2 = new Integer(21); System.out.println(i1 == i2); System.out.println(i1.equals(i2));
輸出結(jié)果:
false
true
如果new
就會(huì)在堆內(nèi)存開(kāi)辟空間,new兩次就開(kāi)辟兩段空間,兩段空間地址值一定不一樣。不推薦這么寫(xiě),過(guò)時(shí)了。
方法
1、從 Number 繼承的 6 個(gè)方法
byteValue()
、shortValue()
、intValue()
、longValue()
、floatValue()
、doubleValue()
2、字符串解析成 int
Integer.parseInt("255");
//將字符串轉(zhuǎn)換為 int 類(lèi)型的數(shù)值,按十進(jìn)制解析成 255
Integer.parseInt("11111111", 2)
//按二進(jìn)制解析成 255
Integer.parseInt("377",8);
//按八進(jìn)制解析成 255
Integer.parseInt("ff", 16);
//按十六進(jìn)制解析成 255
3、進(jìn)制轉(zhuǎn)換
Integer.toBinaryString(255);
//將數(shù)字轉(zhuǎn)成二進(jìn)制,解析成"11111111"
Integer.toOctalString(255);
//將數(shù)字轉(zhuǎn)換成八進(jìn)制,解析成"377"
Integer.toHexString(255);
//將數(shù)字轉(zhuǎn)換成十六進(jìn)制,解析成"ff"
完整程序
System.out.println("i1:" + Integer.parseInt("255")); System.out.println("i2:" + Integer.parseInt("11111111", 2)); System.out.println("i3:" + Integer.parseInt("377", 8)); System.out.println("i4:" + Integer.parseInt("ff", 16)); System.out.println("s1:" + Integer.toBinaryString(255)); System.out.println("s2:" + Integer.toOctalString(255)); System.out.println("s3:" + Integer.toHexString(255));
輸出結(jié)果
255
255
255
255
11111111
377
ff
3、Double
Double
類(lèi)在對(duì)象中包裝了一個(gè)基本類(lèi)型 double
的值。Double 類(lèi)對(duì)象包含一個(gè) double
類(lèi)型的字段。此外,該類(lèi)還提供了多個(gè)方法,可以將 double
類(lèi)型與 String
類(lèi)型相互轉(zhuǎn)換,同時(shí) 還提供了處理 double
類(lèi)型時(shí)比較常用的常量和方法。
創(chuàng)建對(duì)象
Double d1 = 21d; Double d2 = Double.valueOf("21");
方法
1、從Number類(lèi)繼承的6個(gè)方法,同上
2、將數(shù)字字符串轉(zhuǎn)換為 Double 數(shù)值 Double.parseDouble("3.14");
3、判斷浮點(diǎn)數(shù)特殊值
Double.isInfinite(double d):
如果此對(duì)象表示的值是正無(wú)窮大或負(fù)無(wú)窮大,則返回 true;否則返回
Double.isNaN(double d):
如果此 Double 值是一個(gè)非數(shù)字值,則返回 true,否則返回 false
Infinity:無(wú)窮大 NaN:not a number
4、BigDecimal
浮點(diǎn)數(shù)的運(yùn)算是不精確的,我們看以下運(yùn)算
System.out.println(2 - 1.9); System.out.println(4.35 * 100);
運(yùn)算結(jié)果:
那為什么會(huì)出現(xiàn)這種情況呢?
因?yàn)椴徽撌?float
還是 double
都是浮點(diǎn)數(shù),而計(jì)算機(jī)是二進(jìn)制的,浮點(diǎn)數(shù)會(huì)失去一定的精確度。究其根本原因是,十進(jìn)制值通常沒(méi)有完全相同的二進(jìn)制表示形式,十進(jìn)制數(shù)的二進(jìn)制表示形式可能不精確。只能無(wú)限接近于那個(gè)值。
BigDecimal
的作用就是做精確的浮點(diǎn)運(yùn)算
構(gòu)造方法
public BigDecimal(double val) 將double表示形式轉(zhuǎn)換為BigDecimal *不建議使用 public BigDecimal(int val) 將int表示形式轉(zhuǎn)換成BigDecimal public BigDecimal(String val) 將String表示形式轉(zhuǎn)換成BigDecimal * 推薦使用
參數(shù)類(lèi)型為 double
的構(gòu)造方法的結(jié)果有一定的不可預(yù)知性。所以通常情況下不使用。
String
構(gòu)造方法是完全可預(yù)知的:寫(xiě)入 newBigDecimal(“0.1”),
將創(chuàng)建一個(gè) BigDecimal
,它正好等于預(yù)期的 0.1。因此,比較而言,通常建議優(yōu)先使用 String
構(gòu)造方法。
當(dāng) double
必須用作 BigDecimal
的源時(shí),請(qǐng)使用 Double.toString(double
) 轉(zhuǎn)成String
,再使用 String
構(gòu)造方法?;蚴褂?BigDecimal
的靜態(tài)方法 valueOf
。
舉例:使用 double 做構(gòu)造參數(shù)的正確使用
如下程序中 bd1 展示了 參數(shù)類(lèi)型為 double
的構(gòu)造方法的的不可預(yù)知性,db2 展示了 String
的構(gòu)造方法,bd3、bd4 展示了正確使用 double
做為參數(shù)的構(gòu)造方法。
BigDecimal bd1 = new BigDecimal(1.9); BigDecimal bd2 = new BigDecimal("1.9"); BigDecimal bd3 = BigDecimal.valueOf(1.9); BigDecimal bd4 = new BigDecimal(Double.toString(1.9)); System.out.println("db1:" + bd1); System.out.println("db2:" + bd2); System.out.println("db3:" + bd3); System.out.println("db4:" + bd4);
運(yùn)行結(jié)果:
方法
add(BigDecimal bd)+
保留位數(shù),舍入方式)
subtract(BigDecimal bd)-
multiply(BigDecimal bd)*
divide(BigDecimal bd)/
divide(BigDecimal bd,
setScale(保留位數(shù),舍入方式)
舍入運(yùn)算,運(yùn)算結(jié)果會(huì)封裝成新的大數(shù)字對(duì)象返回
舉例:實(shí)現(xiàn)本節(jié)開(kāi)頭的精確運(yùn)算
BigDecimal bd1 = new BigDecimal("2"); BigDecimal bd2 = new BigDecimal("1.9"); System.out.println("2 - 1.9 = " + bd1.subtract(bd2)); BigDecimal bd3 = new BigDecimal("4.35"); BigDecimal bd4 = new BigDecimal("100"); System.out.println("4.35 * 100 = " + bd3.multiply(bd4));
運(yùn)行結(jié)果:
舉例:四舍五入
BigDecimal bd = BigDecimal.valueOf(2.345); double result = bd.setScale(2, RoundingMode.HALF_UP).doubleValue(); System.out.println("result:" + result);
運(yùn)行結(jié)果:
舉例:計(jì)算降落距離
System.out.println("輸入降落時(shí)間"); double t = new Scanner(System.in).nextDouble(); //1/2*9.8*t*t BigDecimal a = BigDecimal.valueOf(0.5); BigDecimal b = BigDecimal.valueOf(9.8); BigDecimal c = BigDecimal.valueOf(t); double result = a.multiply(b).multiply(c.pow(2)).doubleValue(); System.out.println("降落距離:" + result + "米");
運(yùn)行結(jié)果:
5、BigInteger
作用:做超大整數(shù)運(yùn)算
在 Java中,由CPU原生提供的整型最大范圍是 64 位 long 型整數(shù)。使用 long 型整數(shù)可以直接通過(guò) CPU 指令進(jìn)行計(jì)算,速度非???。
如果我們使用的整數(shù)范圍超過(guò)了 long 型怎么辦?這個(gè)時(shí)候,就只能用軟件來(lái)模擬一個(gè)大整數(shù)。java.math.BigInteger
就是用來(lái)表示任意大小的整數(shù)。
我們通過(guò)一個(gè)例子就可以了解它的使用。
舉例:計(jì)算階乘
public class Main { public static void main(String[] args) { System.out.println("輸入數(shù)字來(lái)計(jì)算階乘:"); int number = new Scanner(System.in).nextInt(); System.out.println("階乘結(jié)果:" + f(number)); } private static String f(int number) { //超大整數(shù)運(yùn)算 BigInteger bd = BigInteger.valueOf(number); for (int i = number - 1; i >= 1; i--) { BigInteger bi = BigInteger.valueOf(i); bd = bd.multiply(bi); } return bd.toString(); } }
運(yùn)行結(jié)果:
方法
BigInteger abs()
返回大整數(shù)的絕對(duì)值
BigInteger add(BigInteger val)
返回兩個(gè)大整數(shù)的和
BigInteger and(BigInteger val)
返回兩個(gè)大整數(shù)的按位與的結(jié)果
BigInteger andNot(BigInteger val)
返回兩個(gè)大整數(shù)與非的結(jié)果
BigInteger divide(BigInteger val)
返回兩個(gè)大整數(shù)的商
double doubleValue()
返回大整數(shù)的double類(lèi)型的值
float floatValue()
返回大整數(shù)的float類(lèi)型的值
BigInteger gcd(BigInteger val)
返回大整數(shù)的最大公約數(shù)
int intValue()
返回大整數(shù)的整型值
long longValue()
返回大整數(shù)的long型值
BigInteger max(BigInteger val)
返回兩個(gè)大整數(shù)的最大者
BigInteger min(BigInteger val)
返回兩個(gè)大整數(shù)的最小者
BigInteger mod(BigInteger val)
用當(dāng)前大整數(shù)對(duì)val求模
BigInteger multiply(BigInteger val)
返回兩個(gè)大整數(shù)的積
BigInteger negate()
返回當(dāng)前大整數(shù)的相反數(shù)
BigInteger not()
返回當(dāng)前大整數(shù)的非
BigInteger or(BigInteger val)
返回兩個(gè)大整數(shù)的按位或
BigInteger pow(int exponent)
返回當(dāng)前大整數(shù)的exponent次方
BigInteger remainder(BigInteger val)
返回當(dāng)前大整數(shù)除以val的余數(shù)
BigInteger leftShift(int n)
將當(dāng)前大整數(shù)左移n位后返回
BigInteger rightShift(int n)
將當(dāng)前大整數(shù)右移n位后返回
BigInteger subtract(BigInteger val)
返回兩個(gè)大整數(shù)相減的結(jié)果
byte[] toByteArray(BigInteger val)
將大整數(shù)轉(zhuǎn)換成二進(jìn)制反碼保存在byte數(shù)組中
String toString()
將當(dāng)前大整數(shù)轉(zhuǎn)換成十進(jìn)制的字符串形式
BigInteger xor(BigInteger val)
返回兩個(gè)大整數(shù)的異或
到此這篇關(guān)于JAVA基本類(lèi)型包裝類(lèi) BigDecimal BigInteger
的使用的文章就介紹到這了,更多相關(guān)JAVA BigDecimal、BigInteger 的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IntelliJ IDEA 2020.2 配置大全詳細(xì)圖文教程(更新中)
這篇文章主要介紹了IntelliJ IDEA 2020.2 配置大全(更新中),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08java調(diào)用shell腳本及注意事項(xiàng)說(shuō)明
這篇文章主要介紹了java調(diào)用shell腳本及注意事項(xiàng)說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06Java 服務(wù)端消息推送的實(shí)現(xiàn)小結(jié)
本文主要介紹了Java 服務(wù)端消息推送的實(shí)現(xiàn)小結(jié),主要包括四種常見(jiàn)的消息實(shí)時(shí)推送方案:短輪詢(xún)、長(zhǎng)輪詢(xún)、SSE?和?WebSocket,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10Java語(yǔ)言實(shí)現(xiàn)反轉(zhuǎn)鏈表代碼示例
這篇文章主要介紹了Java語(yǔ)言實(shí)現(xiàn)反轉(zhuǎn)鏈表代碼示例,小編覺(jué)得挺不錯(cuò)的,這里分享給大家,供需要的朋友參考。2017-10-10學(xué)會(huì)Pulsar Consumer的使用方式
這篇文章主要介紹了Pulsar Consumer的使用方式,全文使用大量的代碼來(lái)做了詳細(xì)的講解,感興趣的小伙伴可以參考一下這篇文章,希望讀完能對(duì)你有很大的幫助2021-08-08Jenkins集成sonarQube實(shí)現(xiàn)代碼質(zhì)量檢查過(guò)程圖解
這篇文章主要介紹了Jenkins集成sonarQube實(shí)現(xiàn)代碼質(zhì)量檢查過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09