欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中HashMap 中的一個坑

 更新時間:2022年05月19日 10:07:12   作者:? Java中文社群?  ?  
這篇文章主要介紹了Java中HashMap 中的一個坑,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價價值,需要的小伙伴可以參考一下

前言

最近公司的系統(tǒng)要增加一個新的列表展示功能,功能本身難度并不大,但遇到了一個很“奇怪”的問題。小伙伴在執(zhí)行查詢列表時,明明已經(jīng)使用了 order by 進行排序了,但最終查詢出來的數(shù)據(jù)卻還是亂的。

預(yù)期中的(正確)結(jié)果: 

 現(xiàn)實中的(非預(yù)期)結(jié)果: 

 那到底是哪里出現(xiàn)了問題呢?

問題展示

為了方便展示,我把復(fù)雜的業(yè)務(wù)程序簡化成了以下代碼:

import java.util.HashMap;
public class App {
    public static void main(String[] args) {
        HashMap<String, Object> result = getList();
        result.forEach((k, v) -> {
            System.out.println(k + ":" + v);
        });
    }
    // 查詢方法(簡化版)
    public static HashMap<String, Object> getList() {
        HashMap<String, Object> result = new HashMap<>(); // 最終返回的結(jié)果集
        // 偽代碼:從數(shù)據(jù)庫中查詢出了數(shù)據(jù),然后對數(shù)據(jù)進行處理之后,存到了
        for (int i = 1; i <= 5; i++) {
            result.put("2022-10-" + i, "hello java" + i);
        }
        return result;
    }
}

以上程序的執(zhí)行結(jié)果如下: 

預(yù)期的結(jié)果應(yīng)該是按時間的先后順序展示的,如下圖所示: 

PS:以上示例代碼中,插入元素的順序是有序的(從 1 到 5),相當于實際業(yè)務(wù)場景中的 order by。

原因分析

既然原數(shù)據(jù)使用了 order by 排序,那么原數(shù)據(jù)肯定是沒問題的,那問題就只會出現(xiàn)在返回集 HashMap 上,然后我們再把焦點放到 HashMap 上, 瞬間醒悟,哦,原來如此。HashMap 使用的是哈希方式進行存儲的,因此存入和讀取的順序可能是不一致的,這也說 HashMap 是無序的集合,所以會導致插入的(或 order by 的)順序,與最終展示的順序不一致。

解決方案

經(jīng)過上面的分析我們順利找到了問題,那接下來就是制定相應(yīng)的解決方案了,我想到的解決方案有兩個:

  • 稍微麻煩一點但正確的解決方案:將返回的不確定數(shù)據(jù)類型 HashMap 改為確定的數(shù)據(jù)類型,比如 List;
  • 簡單一點但并不是最優(yōu)的解決方案:將無序的 HashMap 改為有序的 LinkedHashMap,此方案的優(yōu)點是,只需要改動一個單詞就可以解決整個問題了。

第一種解決方案大家都懂這里就不演示了,接下來咱們使用第二種解決方案將上面的問題改造一下,

最終的實現(xiàn)代碼如下:

import java.util.HashMap;
import java.util.LinkedHashMap;
public class App {
    public static void main(String[] args) {
        HashMap<String, Object> result = getList();
        result.forEach((k, v) -> {
            System.out.println(k + ":" + v);
        });
    }

    // 查詢方法(簡化版)
    public static HashMap<String, Object> getList() {
        HashMap<String, Object> result = new LinkedHashMap<>(); // 最終返回的結(jié)果集
        // 偽代碼:從數(shù)據(jù)庫中查詢出了數(shù)據(jù),然后對數(shù)據(jù)進行處理之后,存到了
        for (int i = 1; i <= 5; i++) {
            result.put("2022-10-" + i, "hello java" + i);
        }
        return result;
    }
}

以上程序的執(zhí)行結(jié)果如下: 

 從上述結(jié)果可以看出,當使用 LinkedHashMap 替代了 HashMap 之后,返回的順序就能和插入的順序保持一致了。

LinkedHashMap 的魔力

為什么 HashMap 是無序的,而 LinkedHashMap 卻是有序的呢?

這要從二者的實現(xiàn)說起了,LinkedHashMap 屬于 HashMap 的子類,所以 LinkedHashMap 除了擁有 HashMap 的所有特性之后,還具備自身的一些擴展屬性,其中就包括 LinkedHashMap 中額外維護了一個雙向鏈表,這個雙向鏈表就是用來保存元素的(插入)順序的,這也是為什么 LinkedHashMap 可以實現(xiàn)訪問順序和插入順序一致的原因了。

總結(jié)

本文演示了 HashMap 作為返回類型時隱藏的一個小“坑”,因為 HashMap 本身是無序的,所以它會導致查詢順序和插入順序不一致的問題,對應(yīng)的解決方案有兩種:使用確定的數(shù)據(jù)類型來替代 HashMap,比如 List,或者使用有序的 LinkedHashMap 來替代無序的 HashMap。

到此這篇關(guān)于Java中HashMap 中的一個坑的文章就介紹到這了,更多相關(guān)Java HashMap 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot集成Java DSL的實現(xiàn)代碼

    Spring Boot集成Java DSL的實現(xiàn)代碼

    這篇文章主要介紹了Spring Boot集成Java DSL的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-01-01
  • Java實現(xiàn)FIFO、LRU、LFU、OPT頁面置換算法

    Java實現(xiàn)FIFO、LRU、LFU、OPT頁面置換算法

    本文主要介紹了Java實現(xiàn)FIFO、LRU、LFU、OPT頁面置換算法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • 使用jaxp進行dom解析_動力節(jié)點Java學院整理

    使用jaxp進行dom解析_動力節(jié)點Java學院整理

    這篇文章主要介紹了使用jaxp進行dom解析的相關(guān)資料,需要的朋友可以參考下
    2017-08-08
  • SpringBoot @CompentScan excludeFilters配置無效的解決方案

    SpringBoot @CompentScan excludeFilters配置無效的解決方案

    這篇文章主要介紹了SpringBoot @CompentScan excludeFilters配置無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • JDK安裝與配置超級詳細教程(包含二個或多個JDK的同時安裝)

    JDK安裝與配置超級詳細教程(包含二個或多個JDK的同時安裝)

    這篇文章主要給大家介紹了關(guān)于JDK安裝與配置(包含二個或多個JDK的同時安裝)的相關(guān)資料,對于Java學習者來說,一臺電腦拿到手肯定要配置JDK,但是對于新手來說還是容易出錯,需要的朋友可以參考下
    2023-10-10
  • Java中super關(guān)鍵字介紹以及super()的使用

    Java中super關(guān)鍵字介紹以及super()的使用

    這幾天看到類在繼承時會用到this和super,這里就做了一點總結(jié),下面這篇文章主要給大家介紹了關(guān)于Java中super關(guān)鍵字介紹以及super()使用的相關(guān)資料,需要的朋友可以參考下
    2022-01-01
  • Java中Synchronized鎖的使用和原理詳解

    Java中Synchronized鎖的使用和原理詳解

    這篇文章主要介紹了Java中Synchronized鎖的使用和原理詳解,synchronized是?Java?內(nèi)置的關(guān)鍵字,它提供了一種獨占的加鎖方式,synchronized的獲取和釋放鎖由JVM實現(xiàn),用戶不需要顯示的釋放鎖,非常方便,需要的朋友可以參考下
    2023-07-07
  • 淺談關(guān)于Mybatis的mapper-locations配置問題

    淺談關(guān)于Mybatis的mapper-locations配置問題

    MyBatis 是一款優(yōu)秀的半自動的ORM持久層框架,它支持自定義 SQL、存儲過程以及高級映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作,需要的朋友可以參考下
    2023-05-05
  • java一個接口多個實現(xiàn)類的調(diào)用方式

    java一個接口多個實現(xiàn)類的調(diào)用方式

    這篇文章主要給大家介紹了關(guān)于java一個接口多個實現(xiàn)類的調(diào)用方式的相關(guān)資料,經(jīng)測試確認,當一個接口有多個實現(xiàn)時,調(diào)用時只會執(zhí)行一個,有時候需要多個實現(xiàn)調(diào)用,需要的朋友可以參考下
    2023-09-09
  • Java實現(xiàn)酒店客房管理系統(tǒng)

    Java實現(xiàn)酒店客房管理系統(tǒng)

    這篇文章主要為大家詳細介紹了Java實現(xiàn)酒店客房管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02

最新評論