iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java 中很好用的数据结构EnumSet
  • 407
分享到

Java 中很好用的数据结构EnumSet

2024-04-02 19:04:59 407人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录前言EnumMapEnumSet前言 Java 中常规的集合工具,相比大家都熟练于胸,但是如果说有一个集合类你不一定知道或者说肯定没用过,你相不相信呢?今天跟大家介绍的就是&nb

前言

Java 中常规的集合工具,相比大家都熟练于胸,但是如果说有一个集合类你不一定知道或者说肯定没用过,你相不相信呢?今天跟大家介绍的就是 java.util.EnumMap,也是 java.util 包下面的一个集合类,同样的也有对应的的 java.util.EnumSet,下面我们看一下吧。

Map和 Set 结构在我们日常工作的使用的特别多,经常会用来存放数据或者参数传递,不过有些场景在使用 Map 的时候,不知道大家会不会感受到一丝丝的不安,毕竟 Map 的数据设置我们没办法控制,完全不知道别人会 put 一些什么样的数据进去,或者说如果某些场景我们 Map 的数据 Key 的类型和个数是固定,那在这种情况的下,我们如何提升系统的安全性和性能呢?

这个时候我们就可以考虑使用 EnumMapEnumMap顾名思义首先是一个 Map,其次它的 key只能是枚举,大家都知道枚举中的实例个数是固定的,而且还是预编译的,所以在很大程度上保证了数据的安全性,同时也可以提升一定的性能。

EnumMap

下面我们来看下如何使用 EnumMap,首先我们需要创建一个枚举 Color

package com.ziyou.demo.enums;

public enum Color 
{
  BLUE("blue", "蓝色"),
  RED("red", "红色"),
  ;
  public String color;
  public String desc;

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

在创建一个测试类:

package com.ziyou.demo.enums;

import java.util.EnumMap;


public class ColorTest 
{
  public static void main(String[] args) 
  {
    EnumMap<Color, String> enumMap = new EnumMap<>(Color.class);
    enumMap.put(Color.RED, "我是一个红色枚举");
    enumMap.put(Color.BLUE, "我是一个蓝色枚举");
    System.out.println(enumMap.get(Color.BLUE));
  }
}

 我们可以看到构造 EnumMap 的时候需要传入一个枚举类,后续的 put 和 get 都跟普通的 Map 一样,只不过这个时候 put 的时候 key 必须是该枚举实例了。接下来我们看下EnumMap的 put 和 get 方法是如何实现的,查看 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);
    }

在进行 put的时候,会先进行类型检查,如果说传进来的不是枚举或者说不是在构造的时候指定的枚举,这里就会抛出异常。当类型检查通过以后,会通过枚举的 ordinal() 方法获取该枚举实例的索引,这个方法会返回一个 int 值,返回的值跟枚举在编写的时候的顺序有关系,比如说我们上面创建的 Color 枚举,Color.BLUE.ordinal() 会返回 0Color.RED.ordinal() 会返回 1。拿到索引过后,就会在对应的数组位置上放上 value 值。

 获取数据的时候就更简单了,直接通过 key 获取到索引,然后从数组中那去数据即可。

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

可以看到整个 EnumMap的 put和 get的效率是非常高的,都是在一维数组中直接根据索引定向处理。所以后续大家在类似的场景中可以尝试使用这种方式来提升性能。

EnumSet

说完了 EnumMap 我们再来看看 EnumSetEnumSet 是一个用来操作 Enum 的集合,是一个抽象类,它有两个继承类,JumboEnumSet 和 RegularEnumSet。在使用的时候,需要确定枚举类型。通过下面的方式可以创建一个空的 EnumSet,在后续进行使用。

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的构造方式相对会多一点,我们可以创建空的集合,同时我们也可以直接根据创建一个完整的集合,没必要创建空的然后再进行 add操作,如下所示:

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

另外前面提到会使用到枚举的 ordinal()方式,所以我们在构造 EnumSet 的时候还可以只构造指定两个枚举范围之间的所有枚举值,这里要注意 range方法的第二哥参数的枚举不能在第一个枚举前面。

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

还可以通过 EnumSet的 of 方法来构造指定的枚举集合,通过源码我们可以发现不管是通过什么方法了构造,底层都是先构造一个空集合,然后将对应的枚举元素添加进行。构造空集合的实现逻辑如下,这里我们可以看到,当枚举个数大于 64 的时候,采用的是 JumboEnumSet 这个子类,否则都是 RegularEnumSet这个子类,正常来说一个枚举的实例个数超过 64的会比较少吧。

 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);
    }

到此这篇关于Java 中很好用的数据结构EnumSet的文章就介绍到这了,更多相关java  EnumSet内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java 中很好用的数据结构EnumSet

本文链接: https://www.lsjlt.com/news/148854.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作