Java 中一个你绝对没用过,但是很好用的数据结构

简介: Java 中一个你绝对没用过,但是很好用的数据结构

Java 中一个你绝对没用过,但是很好用的数据结构


✨博主介绍


前言

EnumMap

EnumSet

💫点击直接资料领取💫


✨博主介绍

🌊 作者主页:苏州程序大白


🌊 作者简介:🏆CSDN人工智能域优质创作者🥇,苏州市凯捷智能科技有限公司创始之一,目前合作公司富士康、歌尔等几家新能源公司


💬如果文章对你有帮助,欢迎关注、点赞、收藏


💅 有任何问题欢迎私信,看到会及时回复

💅关注苏州程序大白,分享粉丝福利


前言


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


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


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


EnumMap


下面我们来看下如何使用 EnumMap,首先我们需要创建一个枚举 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>无<br>
 */
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;
/**
 * <br>
 * <b>Function:</b><br>
 * <b>Author:</b><br>
 * <b>Date:</b>2022-04-17 <br>
 * <b>Desc:</b>无<br>
 */
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));
  }
}


632d0356d8c3406a973ca457cdcb585b.png


我们可以看到构造 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()会返回0,Color.RED.ordinal()会返回 1。拿到索引过后,就会在对应的数组位置上放上 value值。


b92e3a34379245aaaa7a6f1262ec3350.png


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


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


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


EnumSet


说完了 EnumMap 我们再来看看 EnumSet,EnumSet 是一个用来操作 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);
    }


相关文章
|
2月前
|
Java
【Java集合类面试二十六】、介绍一下ArrayList的数据结构?
ArrayList是基于可动态扩展的数组实现的,支持快速随机访问,但在插入和删除操作时可能需要数组复制而性能较差。
|
2月前
|
存储 设计模式 算法
JAVA中的常见数据结构
JAVA中的常见数据结构
|
14天前
|
Java
java数据结构,双向链表的实现
文章介绍了双向链表的实现,包括数据结构定义、插入和删除操作的代码实现,以及双向链表的其他操作方法,并提供了完整的Java代码实现。
java数据结构,双向链表的实现
|
14天前
|
存储 Java
java数据结构,线性表链式存储(单链表)的实现
文章讲解了单链表的基本概念和Java实现,包括头指针、尾节点和节点结构。提供了实现代码,包括数据结构、接口定义和具体实现类。通过测试代码演示了单链表的基本操作,如添加、删除、更新和查找元素,并总结了操作的时间复杂度。
java数据结构,线性表链式存储(单链表)的实现
|
8天前
|
存储 安全 Java
Java 数据结构类型总结
在 Java 中,常用的数据结构包括基础数据结构(如数组和字符串)、集合框架(如 Set、List 和 Map 接口的多种实现)、特殊数据结构(如栈、队列和双端队列)、链表(单链表、双链表和循环链表)以及图和树等。这些数据结构各有特点和适用场景,选择时需考虑性能、内存和操作需求。集合框架提供了丰富的接口和类,便于处理对象集合。
|
1天前
|
算法 Java 测试技术
数据结构 —— Java自定义代码实现顺序表,包含测试用例以及ArrayList的使用以及相关算法题
文章详细介绍了如何用Java自定义实现一个顺序表类,包括插入、删除、获取数据元素、求数据个数等功能,并对顺序表进行了测试,最后还提及了Java中自带的顺序表实现类ArrayList。
5 0
|
14天前
|
存储 Java
java数据结构,线性表顺序存储(数组)的实现
文章介绍了Java中线性表顺序存储(数组)的实现。线性表是数据结构的一种,它使用数组来实现。文章详细描述了线性表的基本操作,如增加、查找、删除、修改元素,以及其他操作如遍历、清空、求长度等。同时,提供了完整的Java代码实现,包括MyList接口和MyLinearList实现类。通过main函数的测试代码,展示了如何使用这些方法操作线性表。
|
2月前
|
存储 Java
数据结构中的哈希表(java实现)利用哈希表实现学生信息的存储
这篇文章通过Java代码示例展示了如何实现哈希表,包括定义结点类、链表类、数组存储多条链表,并使用简单的散列函数处理冲突,以及如何利用哈希表存储和查询学生信息。
数据结构中的哈希表(java实现)利用哈希表实现学生信息的存储
|
2月前
|
存储 算法 Java
"解锁Java对象数据结构的奥秘:从基础到实战,与热点技术共舞,让你的编程之路更激情四溢!"
【8月更文挑战第21天】Java以对象为核心,它是程序的基本单元与数据处理的基础。对象源自类,拥有属性(字段)和方法。对象在内存中分为对象头(含哈希码、GC信息等)和实例数据区(存储属性值)。例如,`Student`类定义了姓名、年龄等属性及相应的方法。通过`new`关键字实例化对象并调用其方法进行数据操作,是Java编程的关键技能。
29 0
|
3月前
|
缓存 算法 安全
Java中的数据结构与算法优化策略
Java中的数据结构与算法优化策略