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

Java中如何使用?byte?數(shù)組作為?Map?的?key

 更新時間:2023年06月07日 11:12:03   作者:萬貓學(xué)社  
本文將討論在使用HashMap時,當(dāng)byte數(shù)組作為key時所遇到的問題及其解決方案,介紹使用String和List這兩種數(shù)據(jù)結(jié)構(gòu)作為臨時解決方案的方法,感興趣的朋友跟隨小編一起看看吧

本文將引領(lǐng)我們探索:如何將byte數(shù)組作為HashMap中鍵。HashMap的機制使我們無法直接這樣做。讓我們研究一下,為何出現(xiàn)此狀況,以及針對這種情況,幾種可供選擇的解決方案。

HashMap的工作原理

HashMap是一種使用哈希機制來存儲和檢索值的數(shù)據(jù)結(jié)構(gòu)。使用哈希碼來存儲和檢索值可以大大提高HashMap的性能,因為它可以使查找鍵值對的時間復(fù)雜度保持在 O ( 1 ) O(1) O(1)的級別。當(dāng)然,這也要求我們在實現(xiàn)hashCode()方法時盡可能地讓哈希碼分布均勻,以免造成哈希沖突,從而影響HashMap的效率。

當(dāng)我們調(diào)用put(key, value)方法時,HashMap會通過鍵的hashCode()方法計算哈希碼。這個哈希碼用于確定最終存儲值的桶:

public V get(Object key) {
    Node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}

在使用get(key)方法檢索值時,需要經(jīng)過一系列處理步驟:首先,會通過鍵計算哈希碼,然后找到哈希桶。接下來,使用equals()方法檢查桶中的每個條目是否與鍵相等。最終,返回匹配條目的值:

public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

equalshashCode方法

在Java編程中,equals方法和hashCode方法都有應(yīng)該遵守的規(guī)則。在HashMap這個數(shù)據(jù)結(jié)構(gòu)中,有一個方面尤其重要:具有相同equals方法比較結(jié)果的對象,必須返回相同的哈希值。然而,反之則不一定成立,也就是說,具有相同哈希值的對象,并不一定具有相同的equals方法比較結(jié)果。這也是為什么我們可以將多個對象存儲在HashMap的同一個桶中的原因。

在使用HashMap時,建議不要更改key的哈希值。雖然這不是強制性規(guī)定,但強烈建議將鍵定義為不可變對象。如果對象是不可變的,無論hashCode方法的實現(xiàn)如何,它的哈希值都不會被更改。

在默認情況下,哈希值是基于對象的所有字段進行計算的。如果我們需要使用可變的鍵,我們需要重寫hashCode方法,以確保它的計算不涉及可變字段。為了維護這一個規(guī)則,我們還需要修改equals方法。

使用 byte 數(shù)組作為key

為了能夠從映射中成功地檢索值,相等性必須是有意義的。這就是使用byte數(shù)組并不是一個真正的選擇的主要原因。在Java中,數(shù)組使用對象標識來確定相等性。如果我們使用byte數(shù)組作為key創(chuàng)建HashMap,那么只有使用完全相同的數(shù)組對象才能檢索值。

讓我們使用byte數(shù)組作為key創(chuàng)建一個簡單的例子:

byte[] key1 = {1, 2, 3};
byte[] key2 = {1, 2, 3};
Map<byte[], String> map = new HashMap<>();
map.put(key1, "value1");
map.put(key2, "value2");
System.out.println(map.get(key1));
System.out.println(map.get(key2));
System.out.println(map.get(new byte[]{1, 2, 3}));

我們雖然有兩個相同的鍵,但是我們無法使用具有相同值的新創(chuàng)建的數(shù)組檢索到任何內(nèi)容,運行結(jié)果如下:

value1
value2
null

解決方法

使用String

String的相等性基于字符數(shù)組的內(nèi)容:

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

字符串也是不可變的,并且基于byte數(shù)組創(chuàng)建一個字符串非常簡單。我們可以使用Base64輕松編碼和解碼字符串,然后創(chuàng)建一個使用字符串作為key而不是byte數(shù)組的HashMap:

String key1 = Base64.getEncoder().encodeToString(new byte[]{1, 2, 3});
String key2 = Base64.getEncoder().encodeToString(new byte[]{1, 2, 3});
Map<String, String> map = new HashMap<>();
map.put(key1, "value1");
map.put(key2, "value2");
System.out.println(map.get(key1));
System.out.println(map.get(key2));
System.out.println(map.get(Base64.getEncoder().encodeToString(new byte[]{1, 2, 3})));

運行結(jié)果如下:

value2
value2
value2

注意: 在byte數(shù)組轉(zhuǎn)化為String時會有性能損耗。因此,在大多數(shù)情況下,該解決方案并不推薦。

使用List

String類似,List#equals方法將檢查其每個元素的相等性:

public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;
    ListIterator<E> e1 = listIterator();
    ListIterator<?> e2 = ((List<?>) o).listIterator();
    while (e1.hasNext() && e2.hasNext()) {
        E o1 = e1.next();
        Object o2 = e2.next();
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    }
    return !(e1.hasNext() || e2.hasNext());
}

如果這些元素具有合理的equals()方法并且是不可變的,則List將作為HashMap鍵正確工作。我們只需要確保使用不可變的List實現(xiàn):

List<Byte> key1 = ImmutableList.of((byte) 1, (byte) 2, (byte) 3);
List<Byte> key2 = ImmutableList.of((byte) 1, (byte) 2, (byte) 3);
Map<List<Byte>, String> map = new HashMap<>();
map.put(key1, "value1");
map.put(key2, "value2");
System.out.println(map.get(key1));
System.out.println(map.get(key2));
System.out.println(map.get(ImmutableList.of((byte) 1, (byte) 2, (byte) 3)));

運行結(jié)果如下:

value2
value2
value2

注意: Byte對象的列表將占用比byte數(shù)組更多的內(nèi)存。因此,在大多數(shù)情況下,該解決方案并不推薦。

自定義類(推薦使用)

我們還可以自己的定義一個類,用來完全控制哈希碼計算和相等性。這樣,我們可以確保解決方案快速,并且沒有太大的內(nèi)存占用。

讓我們創(chuàng)建一個只有一個final私有byte數(shù)組字段的類。它將沒有setter方法,只用getter方法,用來確保完全不可變性。

然后在實現(xiàn)自己的equalshashCode方法。為了方法,我們可以使用Arrays類來完成這兩項任務(wù),最終代碼如下:

public class BytesKey {
    private final byte[] array;
    public BytesKey(byte[] array) {
        this.array = array;
    }
    public byte[] getArray() {
        return array.clone();
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()){
            return false;
        }
        BytesKey bytesKey = (BytesKey) o;
        return Arrays.equals(array, bytesKey.array);
    }
    @Override
    public int hashCode() {
        return Arrays.hashCode(array);
    }
}

最后,我們使用我們自定義的類作為HashMap的key:

BytesKey key1 = new BytesKey(new byte[]{1, 2, 3});
BytesKey key2 = new BytesKey(new byte[]{1, 2, 3});
Map<BytesKey, String> map = new HashMap<>();
map.put(key1, "value1");
map.put(key2, "value2");
System.out.println(map.get(key1));
System.out.println(map.get(key2));
System.out.println(map.get(new BytesKey(new byte[]{1, 2, 3})));

運行結(jié)果如下:

value2
value2
value2

注意: 自定義的類既沒有轉(zhuǎn)化為String的性能損耗,也沒有Byte對象列表的內(nèi)存占用。因此,該解決方案推薦使用。

總結(jié)

本文將討論在使用HashMap時,當(dāng)byte數(shù)組作為key時所遇到的問題及其解決方案。

首先,我們將研究為什么不能直接使用數(shù)組作為鍵。在使用HashMap時,我們需要保證每個鍵的唯一性,而使用數(shù)組作為鍵可能會出現(xiàn)沖突。這是因為數(shù)組的hashCode值是基于其在內(nèi)存中的地址計算得出的,因此即使兩個數(shù)組內(nèi)容完全相同,它們在內(nèi)存中的位置不同,它們的hashCode也會不同。因此,直接使用數(shù)組作為鍵可能會導(dǎo)致無法正確獲取值或者出現(xiàn)意外的覆蓋。

接著,我們會介紹使用String和List這兩種數(shù)據(jù)結(jié)構(gòu)作為臨時解決方案的方法。它們都是具有可比性和可哈希性的數(shù)據(jù)結(jié)構(gòu),能夠保證唯一性。但這種方法并不是完美的解決方案,因為使用String或List作為鍵會帶來一些性能上的開銷,或者占用不必要的內(nèi)存空間。

最后,我們將通過自定義類的方式完美解決這個問題。這個自定義類包含了一個byte數(shù)組字段,并重寫hashCodeequals方法,以確保唯一性和正確性。通過這種方式,我們可以避免使用String或List時的性能和內(nèi)存占用問題,并且能夠在保證正確性的同時獲得更高的效率。

到此這篇關(guān)于在Java中使用 byte 數(shù)組作為 Map 的 key的文章就介紹到這了,更多相關(guān)Java使用 byte 數(shù)組作為 Map 的 key內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java編寫實現(xiàn)多人聊天室

    Java編寫實現(xiàn)多人聊天室

    這篇文章主要為大家詳細介紹了Java編寫實現(xiàn)多人聊天室,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Java 中HttpURLConnection附件上傳的實例詳解

    Java 中HttpURLConnection附件上傳的實例詳解

    這篇文章主要介紹了Java 中HttpURLConnection附件上傳的實例詳解的相關(guān)資料,希望通過本文大家能掌握這樣的知識內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • Spring?Native打包本地鏡像的操作方法(無需通過Graal的maven插件buildtools)

    Spring?Native打包本地鏡像的操作方法(無需通過Graal的maven插件buildtools)

    這篇文章主要介紹了Spring?Native打包本地鏡像,無需通過Graal的maven插件buildtools,本文探索一下,如果不通過這個插件來生成鏡像,結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • SpringBoot整合rabbitMq自定義消息轉(zhuǎn)換方式

    SpringBoot整合rabbitMq自定義消息轉(zhuǎn)換方式

    這篇文章主要介紹了SpringBoot整合rabbitMq自定義消息轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java基于動態(tài)規(guī)劃法實現(xiàn)求最長公共子序列及最長公共子字符串示例

    Java基于動態(tài)規(guī)劃法實現(xiàn)求最長公共子序列及最長公共子字符串示例

    這篇文章主要介紹了Java基于動態(tài)規(guī)劃法實現(xiàn)求最長公共子序列及最長公共子字符串,簡單描述了動態(tài)規(guī)劃法的概念、原理,并結(jié)合實例形式分析了Java使用動態(tài)規(guī)劃法求最長公共子序列以及最長公共子字符串相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2018-08-08
  • 淺析java中遍歷map的兩種方式

    淺析java中遍歷map的兩種方式

    本篇文章主要分享了java中遍歷map的兩種方式,代碼簡潔明了,有需要的朋友可以參考下,希望會有所幫助
    2016-12-12
  • 使用java代碼實現(xiàn)保留小數(shù)點的位數(shù)

    使用java代碼實現(xiàn)保留小數(shù)點的位數(shù)

    因為個人應(yīng)用的需要,所以就寫個簡單點的了。希望大家都給給建議,共同學(xué)習(xí)。需要的朋友也可以參考下
    2013-07-07
  • IDEA與MyEclipse代碼量統(tǒng)計方式

    IDEA與MyEclipse代碼量統(tǒng)計方式

    文章介紹在項目中不安裝第三方工具統(tǒng)計代碼行數(shù)的方法,分別說明MyEclipse通過正則搜索(排除空行和注釋)及IDEA使用Statistic插件或調(diào)整搜索設(shè)置(修改ide.usages.page.size)的兩種操作方式,并強調(diào)需根據(jù)需求靈活選擇
    2025-08-08
  • Java源碼解析之object類

    Java源碼解析之object類

    前些天看到別人討論閱讀源碼有什么用這個問題,有一句話說的特別好:學(xué)習(xí)別人實現(xiàn)某個功能的設(shè)計思路,來提高自己的編程水平。本文主要介紹了Java源碼解析之object類,需要的朋友可以參考。
    2017-10-10
  • 重新生成.iml和.idea文件實現(xiàn)方式

    重新生成.iml和.idea文件實現(xiàn)方式

    這篇文章主要介紹了重新生成.iml和.idea文件實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2026-03-03

最新評論

安龙县| 正蓝旗| 东台市| 宽甸| 惠东县| 栾川县| 韶山市| 定兴县| 和硕县| 那曲县| 鄢陵县| 元氏县| 福清市| 克什克腾旗| 二连浩特市| 恩施市| 盐源县| 和田县| 巴楚县| 布尔津县| 漯河市| 大竹县| 霍城县| 府谷县| 磐石市| 滦南县| 会东县| 久治县| 景德镇市| 化州市| 酒泉市| 景谷| 易门县| 云梦县| 资中县| 邹城市| 双流县| 开鲁县| 伊吾县| 永德县| 和静县|