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

Java?中很好用的數(shù)據(jù)結(jié)構(gòu)(你絕對(duì)沒用過(guò))

 更新時(shí)間:2022年05月05日 15:56:14   作者:蘇州程序大白  
今天跟大家介紹的就是?java.util.EnumMap,也是?java.util?包下面的一個(gè)集合類,同樣的也有對(duì)應(yīng)的的?java.util.EnumSet,對(duì)java數(shù)據(jù)結(jié)構(gòu)相關(guān)知識(shí)感興趣的朋友一起看看吧

前言

Java 中常規(guī)的集合工具,相比大家都熟練于胸,但是如果說(shuō)有一個(gè)集合類你不一定知道或者說(shuō)肯定沒用過(guò),你相不相信呢?今天跟大家介紹的就是 java.util.EnumMap,也是 java.util 包下面的一個(gè)集合類,同樣的也有對(duì)應(yīng)的的 java.util.EnumSet,下面我們看一下吧。

MapSet 結(jié)構(gòu)在我們?nèi)粘9ぷ鞯氖褂玫奶貏e多,經(jīng)常會(huì)用來(lái)存放數(shù)據(jù)或者參數(shù)傳遞,不過(guò)有些場(chǎng)景在使用 Map 的時(shí)候,不知道大家會(huì)不會(huì)感受到一絲絲的不安,畢竟 Map 的數(shù)據(jù)設(shè)置我們沒辦法控制,完全不知道別人會(huì) put 一些什么樣的數(shù)據(jù)進(jìn)去,或者說(shuō)如果某些場(chǎng)景我們 Map 的數(shù)據(jù) Key 的類型和個(gè)數(shù)是固定,那在這種情況的下,我們?nèi)绾翁嵘到y(tǒng)的安全性和性能呢?

這個(gè)時(shí)候我們就可以考慮使用 EnumMap,EnumMap 顧名思義首先是一個(gè) Map,其次它的 key 只能是枚舉,大家都知道枚舉中的實(shí)例個(gè)數(shù)是固定的,而且還是預(yù)編譯的,所以在很大程度上保證了數(shù)據(jù)的安全性,同時(shí)也可以提升一定的性能。

EnumMap

下面我們來(lái)看下如何使用 EnumMap,首先我們需要?jiǎng)?chuàng)建一個(gè)枚舉 Color。

package com.ziyou.demo.enums;
/**
 * <br>
 * <b>Function:</b><br>
 * <b>Author:</b><br>
 * <b>Date:</b>2022-04-17 <br>
 * <b>Desc:</b>無(wú)<br>
 */
public enum Color 
{
  BLUE("blue", "藍(lán)色"),
  RED("red", "紅色"),
  ;
  public String color;
  public String desc;

  Color(String color, String desc) 
  {
    this.color = color;
    this.desc = desc;
  }
}

在創(chuàng)建一個(gè)測(cè)試類

package com.ziyou.demo.enums;
import java.util.EnumMap;
/**
 * <br>
 * <b>Function:</b><br>
 * <b>Author:</b><br>
 * <b>Date:</b>2022-04-17 <br>
 * <b>Desc:</b>無(wú)<br>
 */
public class ColorTest 
{
  public static void main(String[] args) 
  {
    EnumMap<Color, String> enumMap = new EnumMap<>(Color.class);
    enumMap.put(Color.RED, "我是一個(gè)紅色枚舉");
    enumMap.put(Color.BLUE, "我是一個(gè)藍(lán)色枚舉");
    System.out.println(enumMap.get(Color.BLUE));
  }
}

我們可以看到構(gòu)造 EnumMap 的時(shí)候需要傳入一個(gè)枚舉類,后續(xù)的 put get 都跟普通的 Map 一樣,只不過(guò)這個(gè)時(shí)候 put 的時(shí)候 key 必須是該枚舉實(shí)例了。接下來(lái)我們看下EnumMapput get 方法是如何實(shí)現(xiàn)的,查看 JDK 源碼我們可以看到。

    public V put(K key, V value) 
    {
        typeCheck(key);
        int index = key.ordinal();
        Object oldValue = vals[index];
        vals[index] = maskNull(value);
        if (oldValue == null)
            size++;
        return unmaskNull(oldValue);
    }

在進(jìn)行 put 的時(shí)候,會(huì)先進(jìn)行類型檢查,如果說(shuō)傳進(jìn)來(lái)的不是枚舉或者說(shuō)不是在構(gòu)造的時(shí)候指定的枚舉,這里就會(huì)拋出異常。當(dāng)類型檢查通過(guò)以后,會(huì)通過(guò)枚舉的 ordinal() 方法獲取該枚舉實(shí)例的索引,這個(gè)方法會(huì)返回一個(gè) int 值,返回的值跟枚舉在編寫的時(shí)候的順序有關(guān)系,比如說(shuō)我們上面創(chuàng)建的 Color 枚舉,Color.BLUE.ordinal() 會(huì)返回 0Color.RED.ordinal() 會(huì)返回 1。拿到索引過(guò)后,就會(huì)在對(duì)應(yīng)的數(shù)組位置上放上 value 值。

獲取數(shù)據(jù)的時(shí)候就更簡(jiǎn)單了,直接通過(guò) key 獲取到索引,然后從數(shù)組中那去數(shù)據(jù)即可。

  public V get(Object key) 
  {
        return (isValidKey(key) ?
                unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);
    }

可以看到整個(gè) EnumMapputget 的效率是非常高的,都是在一維數(shù)組中直接根據(jù)索引定向處理。所以后續(xù)大家在類似的場(chǎng)景中可以嘗試使用這種方式來(lái)提升性能。

EnumSet

說(shuō)完了 EnumMap 我們?cè)賮?lái)看看 EnumSet,EnumSet 是一個(gè)用來(lái)操作 Enum 的集合,是一個(gè)抽象類,它有兩個(gè)繼承類,JumboEnumSet RegularEnumSet。在使用的時(shí)候,需要確定枚舉類型。通過(guò)下面的方式可以創(chuàng)建一個(gè)空的 EnumSet,在后續(xù)進(jìn)行使用。

public static void main(String[] args)
 {
    EnumSet<Color> enumSet = EnumSet.noneOf(Color.class);
    enumSet.add(Color.BLUE);
    enumSet.add(Color.RED);
    System.out.println(enumSet.size());
  }

EnumSet 的構(gòu)造方式相對(duì)會(huì)多一點(diǎn),我們可以創(chuàng)建空的集合,同時(shí)我們也可以直接根據(jù)創(chuàng)建一個(gè)完整的集合,沒必要?jiǎng)?chuàng)建空的然后再進(jìn)行 add 操作,如下所示:

  public static void main(String[] args) 
  {
    EnumSet<Color> enumSet = EnumSet.allOf(Color.class);
    System.out.println(enumSet.size());
  }

另外前面提到會(huì)使用到枚舉的 ordinal() 方式,所以我們?cè)跇?gòu)造 EnumSet 的時(shí)候還可以只構(gòu)造指定兩個(gè)枚舉范圍之間的所有枚舉值,這里要注意 range 方法的第二哥參數(shù)的枚舉不能在第一個(gè)枚舉前面。

EnumSet.range(Color.BLUE,Color.RED);

還可以通過(guò) EnumSetof 方法來(lái)構(gòu)造指定的枚舉集合,通過(guò)源碼我們可以發(fā)現(xiàn)不管是通過(guò)什么方法了構(gòu)造,底層都是先構(gòu)造一個(gè)空集合,然后將對(duì)應(yīng)的枚舉元素添加進(jìn)行。構(gòu)造空集合的實(shí)現(xiàn)邏輯如下,這里我們可以看到,當(dāng)枚舉個(gè)數(shù)大于 64 的時(shí)候,采用的是 JumboEnumSet 這個(gè)子類,否則都是 RegularEnumSet 這個(gè)子類,正常來(lái)說(shuō)一個(gè)枚舉的實(shí)例個(gè)數(shù)超過(guò) 64 的會(huì)比較少吧。

 public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) 
 {
        Enum<?>[] universe = getUniverse(elementType);
        if (universe == null)
            throw new ClassCastException(elementType + " not an enum");
        if (universe.length <= 64)
            return new RegularEnumSet<>(elementType, universe);
        else
            return new JumboEnumSet<>(elementType, universe);
    }

到此這篇關(guān)于Java 中一個(gè)你絕對(duì)沒用過(guò),但是很好用的數(shù)據(jù)結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)java數(shù)據(jù)結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

玉田县| 梁平县| 华亭县| 赞皇县| 丰都县| 民权县| 克什克腾旗| 临西县| 泗水县| 友谊县| 全椒县| 田东县| 黄龙县| 荆门市| 潼南县| 即墨市| 漯河市| 滁州市| 昌吉市| 尼玛县| 东安县| 偃师市| 长春市| 无锡市| 汾阳市| 自治县| 怀仁县| 嘉黎县| 宝兴县| 云和县| 丹巴县| 荔波县| 汤原县| 夏邑县| 那坡县| 哈巴河县| 麻城市| 东至县| 樟树市| 东城区| 松江区|