最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

工作中Java集合的規(guī)范使用操作詳解

 更新時間:2022年11月29日 10:04:16   作者:卡布奇諾-海晨  
這篇文章主要為大家詳細介紹了工作中Java集合使用時需要注意的規(guī)范,文中的示例代碼講解詳細,對我們使用Java集合有一定的幫助,感興趣的可以了解一下

一、前言

現(xiàn)代軟件行業(yè)的高速發(fā)展對開發(fā)者的綜合素質(zhì)要求越來越高,因為不僅是編程知識點,其它維度的知識點也會影響到軟件的最終交付質(zhì)量。比如:五花八門的錯誤碼會人為地增加排查問題的難度;數(shù)據(jù)庫的表結(jié)構和索引設計缺陷帶來的系統(tǒng)架構缺陷或性能風險;工程結(jié)構混亂導致后續(xù)項目維護艱難;沒有鑒權的漏洞代碼容易被黑客攻擊等。依據(jù)約束力強弱及故障敏感性,規(guī)約依次分為【強制】、【推薦】、【參考】三大類。在延伸的信息中,“說明”對規(guī)約做了適當擴展和解釋;“正例”提倡什么樣的編碼和實現(xiàn)方式;“反例”說明需要提防的雷區(qū),以及真實的錯誤案例。

現(xiàn)代軟件架構的復雜性需要協(xié)同開發(fā)完成,如何高效地協(xié)同呢?無規(guī)矩不成方圓,無規(guī)范難以協(xié)同,比如,制定交通法規(guī)表面上是要限制行車權,實際上是保障公眾的人身安全,試想如果沒有限速,沒有紅綠燈,誰還敢上路行駛?對軟件來說,適當?shù)囊?guī)范和標準絕不是消滅代碼內(nèi)容的創(chuàng)造性、優(yōu)雅性,而是限制過度個性化,以一種普遍認可的統(tǒng)一方式一起做事,提升協(xié)作效率,降低溝通成本。代碼的字里行間流淌的是軟件系統(tǒng)的血液,代碼質(zhì)量的提升是盡可能少踩坑,杜絕踩重復的坑,切實提升系統(tǒng)穩(wěn)定性,碼出質(zhì)量。

二、規(guī)范使用Java集合

1.【強制】關于 hashCode 和 equals 的處理,遵循如下規(guī)則:

1)只要覆寫 equals,就必須覆寫 hashCode。

2)因為 Set 存儲的是不重復的對象,依據(jù) hashCode 和 equals 進行判斷,所以 Set 存儲的對象必須覆寫這兩種方法。

3)如果自定義對象作為 Map 的鍵,那么必須覆寫 hashCode 和 equals。

說明:String 因為覆寫了 hashCode 和 equals 方法,所以可以愉快地將 String 對象作為 key 來使用。

2.【強制】判斷所有集合內(nèi)部的元素是否為空,使用 isEmpty() 方法,而不是 size() == 0 的方式。

說明:在某些集合中,前者的時間復雜度為 O(1),而且可讀性更好。

正例:

Map<String, Object> map = new HashMap<>(16);
if (map.isEmpty()) {
System.out.println("no element in this map.");
}

3.【強制】在使用 java.util.stream.Collectors 類的 toMap() 方法轉(zhuǎn)為 Map 集合時,一定要使用參數(shù)類型為 BinaryOperator,參數(shù)名為 mergeFunction 的方法,否則當出現(xiàn)相同 key 時會拋出

IllegalStateException 異常。

說明:參數(shù) mergeFunction 的作用是當出現(xiàn) key 重復時,自定義對 value 的處理策略。

正例:

List<Pair<String, Double>> pairArrayList = new ArrayList<>(3);
pairArrayList.add(new Pair<>("version", 12.10));
pairArrayList.add(new Pair<>("version", 12.19));
pairArrayList.add(new Pair<>("version", 6.28));
// 生成的 map 集合中只有一個鍵值對:{version=6.28}
Map<String, Double> map = pairArrayList.stream()
.collect(Collectors.toMap(Pair::getKey, Pair::getValue, (v1, v2) -> v2));

反例:

String[] departments = new String[]{"RDC", "RDC", "KKB"};
// 拋出 IllegalStateException 異常
Map<Integer, String> map = Arrays.stream(departments)
.collect(Collectors.toMap(String::hashCode, str -> str));

4.【強制】在使用 java.util.stream.Collectors 類的 toMap() 方法轉(zhuǎn)為 Map 集合時,一定要注意當 value為 null 時會拋 NPE 異常。

說明:在 java.util.HashMap 的 merge 方法里會進行如下的判斷:

if (value == null || remappingFunction == null)
throw new NullPointerException();

反例:

List<Pair<String, Double>> pairArrayList = new ArrayList<>(2);
pairArrayList.add(new Pair<>("version1", 8.3));
pairArrayList.add(new Pair<>("version2", null));
// 拋出 NullPointerException 異常
Map<String, Double> map = pairArrayList.stream()
.collect(Collectors.toMap(Pair::getKey, Pair::getValue, (v1, v2) -> v2));

5.【強制】ArrayList 的 subList 結(jié)果不可強轉(zhuǎn)成 ArrayList,否則會拋出 ClassCastException 異常:java.util.RandomAccessSubList cannot be cast to java.util.ArrayList。

說明:subList() 返回的是 ArrayList 的內(nèi)部類 SubList,并不是 ArrayList 本身,而是 ArrayList 的一個視圖,對于SubList 的所有操作最終會反映到原列表上。同時注意數(shù)組越界異常。

6.【強制】使用 Map 的方法 keySet() / values() / entrySet() 返回集合對象時,不可以對其進行添加元素操作,否則會拋出 UnsupportedOperationException 異常。

7.【強制】Collections 類返回的對象,如:emptyList() / singletonList() 等都是 immutable list,不可對其進行添加或者刪除元素的操作。

反例:如果查詢無結(jié)果,返回 Collections.emptyList() 空集合對象,調(diào)用方一旦在返回的集合中進行了添加元素的操作,就會觸發(fā) UnsupportedOperationException 異常。

8.【強制】在 subList 場景中,高度注意對父集合元素的增加或刪除,均會導致子列表的遍歷、增加、刪除產(chǎn)生 ConcurrentModificationException 異常。

說明:抽查表明,90% 的程序員對此知識點都有錯誤的認知。

9.【強制】使用集合轉(zhuǎn)數(shù)組的方法,必須使用集合的 toArray(T[] array),傳入的是類型完全一致、長度為0 的空數(shù)組。

反例:直接使用 toArray 無參方法存在問題,此方法返回值只能是 Object[]類,若強轉(zhuǎn)其它類型數(shù)組將出現(xiàn)ClassCastException 錯誤。

正例:

List<String> list = new ArrayList<>(2);
list.add("guan");
list.add("bao");
String[] array = list.toArray(new String[0]);

說明:使用 toArray 帶參方法,數(shù)組空間大小的 length:

1)等于 0,動態(tài)創(chuàng)建與 size 相同的數(shù)組,性能最好。

2)大于 0 但小于 size,重新創(chuàng)建大小等于 size 的數(shù)組,增加 GC 負擔。

3)等于 size,在高并發(fā)情況下,數(shù)組創(chuàng)建完成之后,size 正在變大的情況下,負面影響與 2 相同。

4)大于 size,空間浪費,且在 size 處插入 null 值,存在 NPE 隱患。

10.【強制】使用 Collection 接口任何實現(xiàn)類的 addAll() 方法時,要對輸入的集合參數(shù)進行 NPE 判斷。

說明:在 ArrayList#addAll 方法的第一行代碼即 Object[] a = c.toArray();其中 c 為輸入集合參數(shù),如果為 null,則直接拋出異常。

11.【強制】使用工具類 Arrays.asList() 把數(shù)組轉(zhuǎn)換成集合時,不能使用其修改集合相關的方法,它的 add/ remove / clear 方法會拋出 UnsupportedOperationException 異常。

說明:asList 的返回對象是一個 Arrays 內(nèi)部類,并沒有實現(xiàn)集合的修改方法。Arrays.asList 體現(xiàn)的是適配器模式,只是轉(zhuǎn)換接口,后臺的數(shù)據(jù)仍是數(shù)組。

String[] str = new String[]{ "yang", "guan", "bao" };
List list = Arrays.asList(str);

第一種情況:list.add("yangguanbao"); 運行時異常。

第二種情況:str[0] = "change"; list 中的元素也會隨之修改,反之亦然。

12.【強制】泛型通配符<? extends T>來接收返回的數(shù)據(jù),此寫法的泛型集合不能使用 add 方法,而<? super T>不能使用 get 方法,兩者在接口調(diào)用賦值的場景中容易出錯。

說明:擴展說一下 PECS(Producer Extends Consumer Super) 原則,即頻繁往外讀取內(nèi)容的,適合用<? extends T>,經(jīng)常往里插入的,適合用<? super T>

13.【強制】在無泛型限制定義的集合賦值給泛型限制的集合時,在使用集合元素時,需要進行instanceof 判斷,避免拋出 ClassCastException 異常。

說明:畢竟泛型是在 JDK5 后才出現(xiàn),考慮到向前兼容,編譯器是允許非泛型集合與泛型集合互相賦值。

反例:

List<String> generics = null;
List notGenerics = new ArrayList(10);
notGenerics.add(new Object());
notGenerics.add(new Integer(1));
generics = notGenerics;
// 此處拋出 ClassCastException 異常
String string = generics.get(0);

14.【強制】不要在 foreach 循環(huán)里進行元素的 remove / add 操作。remove 元素請使用 iterator 方式,如果并發(fā)操作,需要對 iterator 對象加鎖。

正例:

List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (刪除元素的條件) {
iterator.remove();
}
}

反例:

for (String item : list) {
if ("1".equals(item)) {
list.remove(item);
}
}

說明:反例中的執(zhí)行結(jié)果肯定會出乎大家的意料,那么試一下把“1”換成“2”會是同樣的結(jié)果嗎?

15.【強制】在 JDK7 版本及以上,Comparator 實現(xiàn)類要滿足如下三個條件,不然 Arrays.sort,Collections.sort 會拋 IllegalArgumentException 異常。

說明:三個條件如下

1)x,y 的比較結(jié)果和 y,x 的比較結(jié)果相反。

2)x > y,y > z,則 x > z。

3)x = y,則 x,z 比較結(jié)果和 y,z 比較結(jié)果相同。

反例:下例中沒有處理相等的情況,交換兩個對象判斷結(jié)果并不互反,不符合第一個條件,在實際使用中可能會出現(xiàn)異常。

new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getId() > o2.getId() ? 1 : -1;
}
};

16.【推薦】泛型集合使用時,在 JDK7 及以上,使用 diamond 語法或全省略。

說明:菱形泛型,即 diamond,直接使用<>來指代前邊已經(jīng)指定的類型。

正例:

// diamond 方式,即<>
HashMap<String, String> userCache = new HashMap<>(16);
// 全省略方式
ArrayList<User> users = new ArrayList(10);

17.【推薦】集合初始化時,指定集合初始值大小。

說明:HashMap 使用構造方法 HashMap(int initialCapacity) 進行初始化時,如果暫時無法確定集合大小,那么指定默認值(16)即可。

正例:initialCapacity = (需要存儲的元素個數(shù) / 負載因子) + 1。注意負載因子(即 loaderfactor)默認為 0.75,如果暫時無法確定初始值大小,請設置為 16(即默認值)。

反例:HashMap 需要放置 1024 個元素,由于沒有設置容量初始大小,隨著元素增加而不斷擴容,resize() 方法總共會調(diào)用 8 次,反復重建哈希表和數(shù)據(jù)遷移。當放置的集合元素個數(shù)達千萬級時會影響程序性能。

18.【推薦】使用 entrySet 遍歷 Map 類集合 KV,而不是 keySet 方式進行遍歷。

說明:keySet 其實是遍歷了 2 次,一次是轉(zhuǎn)為 Iterator 對象,另一次是從 hashMap 中取出 key 所對應的 value。而entrySet 只是遍歷了一次就把 key 和 value 都放到了 entry 中,效率更高。如果是 JDK8,使用 Map.forEach 方法。

正例:values() 返回的是 V 值集合,是一個 list 集合對象;keySet() 返回的是 K 值集合,是一個 Set 集合對象;entrySet() 返回的是 K-V 值組合的 Set 集合。

19、【推薦】高度注意 Map 類集合 K / V 能不能存儲 null 值的情況,如下表格:

 反例: 由于 HashMap 的干擾,很多人認為 ConcurrentHashMap 是可以置入 null 值,而事實上,存儲 null 值時會拋 出 NPE 異常。

20.【參考】合理利用好集合的有序性(sort)和穩(wěn)定性(order),避免集合的無序性(unsort)和不穩(wěn)定性(unorder)帶來的負面影響。

說明:有序性是指遍歷的結(jié)果是按某種比較規(guī)則依次排列的,穩(wěn)定性指集合每次遍歷的元素次序是一定的。如:ArrayList 是 order / unsort;HashMap 是 unorder / unsort;TreeSet 是 order / sort。

21.【參考】利用 Set 元素唯一的特性,可以快速對一個集合進行去重操作,避免使用 List 的contains() 進行遍歷去重或者判斷包含操作。

到此這篇關于工作中Java集合的規(guī)范使用操作詳解的文章就介紹到這了,更多相關Java集合內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot集成Elasticsearch過程實例

    SpringBoot集成Elasticsearch過程實例

    這篇文章主要介紹了SpringBoot集成Elasticsearch過程實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • Mybatis的動態(tài)Sql組合模式詳情

    Mybatis的動態(tài)Sql組合模式詳情

    這篇文章主要介紹了Mybatis的動態(tài)Sql組合模式詳情,這篇文章從組合模式的角度分析了Mybatis動態(tài)sql的部分,SqlNode是組合模式的Component接口,更多相關內(nèi)容需要的小伙伴可以參考一下
    2022-08-08
  • Mybatis統(tǒng)計sql運行時間的兩種方式

    Mybatis統(tǒng)計sql運行時間的兩種方式

    這篇文章主要介紹了Mybatis統(tǒng)計sql運行時間的方案,Spring?Boot?+?Mybatis?web項目,統(tǒng)計sql運行時間,用于分析慢sql,優(yōu)化系統(tǒng)速度,方案有兩種:自定義實現(xiàn)?Interceptor和使用現(xiàn)有依賴庫(Druid),文中通過代碼示例講解的非常詳細,需要的朋友可以參考下
    2024-11-11
  • 解決IDEA報錯java無效的目標發(fā)行版:22

    解決IDEA報錯java無效的目標發(fā)行版:22

    在使用IDEA編譯項目時,可能會遇到JDK版本不一致的錯誤,這篇文章主要介紹了解決IDEA報錯java無效的目標發(fā)行版:22的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-10-10
  • Groovy的規(guī)則腳本引擎實例解讀

    Groovy的規(guī)則腳本引擎實例解讀

    這篇文章主要介紹了Groovy的規(guī)則腳本引擎實例解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 自己手寫Mybatis通用batchInsert問題

    自己手寫Mybatis通用batchInsert問題

    這篇文章主要介紹了自己手寫Mybatis通用batchInsert問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • SpringBoot集成Mybatis的實現(xiàn)步驟

    SpringBoot集成Mybatis的實現(xiàn)步驟

    這篇文章主要介紹了SpringBoot集成Mybatis的實現(xiàn)步驟,本文通過SpringBoot +MyBatis 實現(xiàn)對數(shù)據(jù)庫學生表的查詢操作,需要的朋友可以參考下
    2020-12-12
  • SpringAMQP消息隊列(SpringBoot集成RabbitMQ方式)

    SpringAMQP消息隊列(SpringBoot集成RabbitMQ方式)

    這篇文章主要介紹了SpringAMQP消息隊列(SpringBoot集成RabbitMQ方式),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • mybatis 批量將list數(shù)據(jù)插入到數(shù)據(jù)庫的實現(xiàn)

    mybatis 批量將list數(shù)據(jù)插入到數(shù)據(jù)庫的實現(xiàn)

    這篇文章主要介紹了mybatis 批量將list數(shù)據(jù)插入到數(shù)據(jù)庫的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • SpringBoot查詢數(shù)據(jù)庫導出報表文件方式

    SpringBoot查詢數(shù)據(jù)庫導出報表文件方式

    這篇文章主要介紹了SpringBoot查詢數(shù)據(jù)庫導出報表文件方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04

最新評論

道孚县| 和林格尔县| 苏尼特右旗| 砀山县| 和田县| 利辛县| 中超| 太原市| 环江| 普宁市| 育儿| 北碚区| 嵊泗县| 九台市| 天祝| 大竹县| 兴国县| 华阴市| 青阳县| 宁都县| 龙州县| 米易县| 尚义县| 苏尼特右旗| 崇左市| 揭西县| 美姑县| 廊坊市| 武宁县| 敦化市| 临沭县| 乐昌市| 瑞安市| 北海市| 丰镇市| 砚山县| 吴忠市| 淅川县| 南昌市| 洪泽县| 榆林市|