Java中不常用但很好用的開(kāi)發(fā)小技巧分享
其實(shí)干 Java
開(kāi)發(fā),必然離不開(kāi)一些計(jì)算,比如如果你現(xiàn)在工作是服務(wù)與銀行,那么就會(huì)對(duì)金額這些計(jì)算非常敏感,所以就會(huì)經(jīng)常用到 BigDecimal
,如果你入職的是其他行業(yè)的公司,可能用的就相對(duì)沒(méi)這么多,今天了不起就來(lái)給大家分項(xiàng)一下那些不怎么常用,但是非常有用的方法。
BigDecimal
關(guān)于 BigDecimal
的加減乘除,了不起在這里就不再一一的去給大家說(shuō)了,畢竟這都是非?;A(chǔ)的內(nèi)容,我們來(lái)說(shuō)說(shuō)需要大家掌握的有用的方法。
我們先來(lái)看一段代碼:
BigDecimal?b1=?new?BigDecimal(0.1); System.out.println(b1);
大家可以猜一下這個(gè)執(zhí)行的結(jié)果會(huì)是什么內(nèi)容呢?
結(jié)果是 0.1 么?如果不是 0.1 的話,那么執(zhí)行輸出的話,會(huì)出現(xiàn)什么內(nèi)容,如果你知道,那么恭喜你,如果你不知道的話,那么就得認(rèn)真學(xué)習(xí)一下拉。
結(jié)果顯而易見(jiàn),肯定不是 0.1 。
我們看看他的執(zhí)行結(jié)果是什么內(nèi)容,然后再來(lái)說(shuō),應(yīng)該使用什么方式。
0.1000000000000000055511151231257827021181583404541015625
當(dāng)看到這個(gè)內(nèi)容的,很多人恍然大悟,一眼就看出來(lái),精度丟失了,所以導(dǎo)致了這種情況的發(fā)生,成這種問(wèn)題的原因是 0.1 這個(gè)數(shù)字計(jì)算機(jī)是無(wú)法精確表示的,送給 BigDecimal
的時(shí)候就已經(jīng)丟精度了.double類(lèi)型 那么我們應(yīng)該怎么去處理這個(gè) double
類(lèi)型的參數(shù)呢?
其實(shí)很簡(jiǎn)單,方式有兩種,第一種:
BigDecimal?bigDecimal?=?new?BigDecimal("0.1"); System.out.println(bigDecimal);
第二種:
BigDecimal?bigDecimal1?=?BigDecimal.valueOf(0.1); System.out.println(bigDecimal1);
實(shí)際上,在本質(zhì)上,這兩個(gè)方法并沒(méi)有區(qū)別,因?yàn)椤?code>valueOf 在實(shí)現(xiàn)上,就是轉(zhuǎn)成了一個(gè)字符串。
BigDecimal
當(dāng)中的 valueOf
中是把浮點(diǎn)數(shù)轉(zhuǎn)換成了字符串來(lái)構(gòu)造的 BigDecimal
,因此避免了問(wèn)題。
源碼如下:
compareTo
這個(gè)方法我們經(jīng)常用到,用來(lái)比較 BigDecimal
的,在 BigDecimal
中使用 equals
可能會(huì)導(dǎo)致結(jié)果錯(cuò)誤,BigDecimal
中提供了 compareTo
方法,在很多時(shí)候需要使用 compareTo
比較兩個(gè)值。如下所示:
????????BigDecimal?b1?=?new?BigDecimal("10.0"); ????????BigDecimal?b2?=?new?BigDecimal("10.00"); ????????System.out.println(b1.equals(b2)); ????????System.out.println(b1.compareTo(b2));
我們肯定遇到過(guò)這種,用 compareTo
比較的時(shí)候,自己臆想的和代碼執(zhí)行的,肯定不一樣,于是就有了自己實(shí)驗(yàn)的過(guò)程。
出現(xiàn)此種結(jié)果的原因是,equals不僅比較了值是否相等,還比較了精度是否相同。示例中,由于兩個(gè)值的精度不同,所有結(jié)果也就不相同。而 compareTo 是只比較值的大小。返回的值為-1(小于),0(等于),1(大于)。
List
說(shuō)到 List 絕對(duì)不陌生,甚至天天在用,List 轉(zhuǎn)數(shù)組,應(yīng)該怎么操作呢?
其實(shí)很簡(jiǎn)單,就是 toArray。
toArray
List<String>?list?=?new?ArrayList<>(); String[]?strings?=?list.toArray(new?String[list.size()]);
兩個(gè)方法,不帶參數(shù)的 toArray
就是直接調(diào)用 Arrays.copyOf(elementData, size)
,將 List
中的元素對(duì)象的引用裝在一個(gè)新的生成數(shù)組中。
帶參數(shù)的則是會(huì)返回指定類(lèi)型(必須為 List
元素類(lèi)型的父類(lèi)或本身)的數(shù)組對(duì)象,如果 a.length
小于 List
元素個(gè)數(shù)就直接調(diào)用 Arrays
的 copyOf()
方法進(jìn)行拷貝并且返回新數(shù)組對(duì)象,新數(shù)組中也是裝的 List
元素對(duì)象的引用,否則先調(diào)用System.arraycopy()
將 List
元素對(duì)象的引用裝在a數(shù)組中,如果a數(shù)組還有剩余的空間,則在 a[size]
放置一個(gè) null
,size
就是 list
中元素的個(gè)數(shù),這個(gè) null
值可以使得 toArray(T[] a)
方法調(diào)用者可以判斷 null
后面已經(jīng)沒(méi)有 list
元素了.
其實(shí)在業(yè)務(wù)中,我們更多的都是直接使用第二個(gè),第一個(gè)五參數(shù)的方法,很多時(shí)候都是作為測(cè)試來(lái)存在的。
JDK8的小玩意
其實(shí)了不起更想說(shuō)的,還是 JDK8 中的一些肖操作,他會(huì)精簡(jiǎn)我們的代碼,而且,邏輯也更加的清晰,為什么這么說(shuō),因?yàn)楝F(xiàn)在百分之八九十的公司都還是在使用 JDK8 ,升級(jí)版本的,還并不是那么的多,畢竟很少有公司會(huì)吧之前的項(xiàng)目隨便更換某些必要的依賴(lài)的版本號(hào),除非迫不得已。
flatMap
其實(shí)這個(gè)方法,是真的不常用,因?yàn)槲覀冇玫降?,很多都?nbsp;forEach
,或者 filter
,或者 map
這些都是我們比較常用的。
而 flatMap
相當(dāng)于 map+flat,通過(guò) map 把每一個(gè)元素替換為一個(gè)流,然后展開(kāi)這個(gè)流。比如,我們要統(tǒng)計(jì)所有訂單的總價(jià)格,可以有兩種方式:
就是 Order 里面有一個(gè) Detail 的信息,而這個(gè) Order 是一個(gè) List 而 Detail 也是一個(gè) List,就比如下面
public?class?Order?{ private?String?id; private?List<Detail>?details; } public?class?Order?{ private?String?productId; private?Double?productPrice; private?Integer?productQuantity; }
如果我們想要統(tǒng)計(jì)訂單總價(jià),如果 Order 表中已經(jīng)存在了這個(gè)價(jià)格這塊的內(nèi)容了,那當(dāng)然好,如果沒(méi)有,那么就得去匯總詳情了,不是么?
//求和使用flatMap orders.stream().flatMap(order?->?order.getDetails().stream()).mapToDouble(item?->?item.getProductQuantity()?*?item.getProductPrice()).sum(); //求和使用flatMapToDouble orders.stream().flatMapToDouble(order ->order.getDetails().stream().mapToDouble(item -> item.getProductQuantity()?* item.getProductPrice())).sum();
其實(shí),了不起覺(jué)得,JDK8 中才是真的有很多了不起的內(nèi)容,再比如我們統(tǒng)計(jì)list中的數(shù)據(jù),已經(jīng)不在需要自己去做for循環(huán)來(lái)進(jìn)行比對(duì)了,而是直接通過(guò)方法來(lái)獲取。
//獲取最大 Integer?id?=?userList.stream().map(User::getId).max(Integer::compareTo).get(); //獲取最小 Integer?id1?=?userList.stream().map(User::getId).min(Integer::compareTo).get(); //獲取id數(shù)量 long?count?=?userList.stream().map(User::getId).count(); //總和 int?sum?=?userList.stream().mapToInt(User::getId).sum(); //獲取平均值 double?d?=?userList.stream().mapToInt(User::getId).average().getAsDouble();
分組統(tǒng)計(jì)
??//分組統(tǒng)計(jì) ????Map<String,?Long>?map?=?userList.stream().collect(Collectors.groupingBy(User::getName,?Collectors.counting())); ??//分組?Collectors.groupingBy(屬性名) ?Map<Integer,?List<Person>>?map?=?list.stream().collect(Collectors.groupingBy(Person::getAge)); ????//將名字全轉(zhuǎn)換為大寫(xiě) ????List<String>?list?=?userList.stream().map(User::getName).map(String::toUpperCase).collect(Collectors.toList()); ????//獲取忽略第一個(gè)并取前幾條數(shù)據(jù) ????List<User>?list1?=?userList.stream().skip(1).limit(2).collect(Collectors.toList()); ????//distinct()?去重;collect(Collectors.toList())。封裝成集合 ????List<User>?collect?=?userList.stream().distinct().collect(Collectors.toList());
關(guān)于這些不常用,但是非常有用的內(nèi)容,你學(xué)會(huì)了么?
到此這篇關(guān)于Java中不常用但很好用的開(kāi)發(fā)小技巧分享的文章就介紹到這了,更多相關(guān)Java開(kāi)發(fā)技巧內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java計(jì)算自?xún)鐢?shù)和水仙花數(shù)
對(duì)于一個(gè)正整數(shù)而言,長(zhǎng)度是n,如果它的各位上的數(shù)字的n次方之和正好等于它本身,那么我們稱(chēng)這樣的數(shù)為自?xún)鐢?shù),下面使用JAVA實(shí)現(xiàn)這個(gè)方法2014-03-03java數(shù)據(jù)結(jié)構(gòu)基礎(chǔ):稀疏數(shù)組
今天帶大家了解一下Java稀疏數(shù)組的相關(guān)知識(shí),文中有非常詳細(xì)的介紹及代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下2021-08-08Java中回調(diào)函數(shù)?(callback)?及其實(shí)際應(yīng)用場(chǎng)景
在Java中回調(diào)函數(shù)(Callback)是一種常見(jiàn)的設(shè)計(jì)模式,用于實(shí)現(xiàn)異步操作或事件處理,這篇文章主要給大家介紹了關(guān)于Java中回調(diào)函數(shù)?(callback)?及其實(shí)際應(yīng)用場(chǎng)景的相關(guān)資料,需要的朋友可以參考下2024-02-02Java實(shí)現(xiàn)創(chuàng)建Zip壓縮包并寫(xiě)入文件
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)創(chuàng)建Zip壓縮包并寫(xiě)入文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01Java線程池隊(duì)列PriorityBlockingQueue和SynchronousQueue詳解
這篇文章主要為大家介紹了Java線程池隊(duì)列PriorityBlockingQueue和SynchronousQueue詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12Java的Jackson庫(kù)的使用及其樹(shù)模型的入門(mén)學(xué)習(xí)教程
這篇文章主要介紹了Java的Jackson庫(kù)的使用及其樹(shù)模型入門(mén)學(xué)習(xí)教程,Jackson庫(kù)通常被用來(lái)作Java對(duì)象和JSON的互相轉(zhuǎn)換,需要的朋友可以參考下2016-01-01Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出的實(shí)現(xiàn)過(guò)程
這篇文章主要介紹了Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11