首页 > 其他分享 >枚举

枚举

时间:2024-08-07 15:08:52浏览次数:7  
标签:常量 EnumSet 枚举 EnumMap 类型 Day

枚举

1.枚举的定义

Java中的枚举(Enumeration)是一种特殊的数据类型,用于定义一组有限的命名常量。枚举提供了一种更直观、更可读的方式来表示一组相关的常量,并且可以为这些常量绑定其他数据或行为。枚举是在JDK 1.5(Java 5)以后引入的,它是对之前使用常量(如public static final变量)表示一组固定值的方式的一种改进。

枚举的特性

  1. 有限性:枚举类型的对象个数是有限的,在定义枚举时就已经确定。
  2. 类型安全:枚举类型提供了一种类型安全的方式来表示一组常量,避免了使用整型常量时可能发生的类型不匹配问题。
  3. 可读性:枚举常量提供了更好的可读性,使得代码更加直观易懂。
  4. 可扩展性:虽然枚举类型的对象个数是有限的,但枚举类型本身可以包含方法、构造器、字段等,从而增加了其可扩展性。

枚举的作用

  1. 定义一组有限的常量集合:枚举提供了一种定义一组有限命名常量的方式。这些常量可以是任何类型的数据,但通常在枚举中它们被用作表示特定含义的标识符。例如,可以定义一个表示星期的枚举,包括MONDAYTUESDAY等常量。
  2. 提供类型安全:使用枚举可以增加代码的类型安全性。枚举常量是枚举类型的一个实例,这意味着在编译时就可以检查类型是否匹配,从而避免了运行时错误。与使用整型常量或字符串常量相比,枚举类型更加安全,因为它限制了可以赋给枚举变量的值的范围。
  3. 提高代码可读性:枚举常量的名称通常比整数或字符串更具描述性,因此使用枚举可以提高代码的可读性。通过枚举常量的名称,可以很容易地理解代码中的意图,而无需查阅额外的文档或注释。
  4. 易于维护:由于枚举常量是在一个地方定义的,因此当需要修改或扩展常量集合时,只需要修改枚举定义即可。这有助于减少代码中的重复,并使得代码更加易于维护。
  5. 支持方法和属性:枚举类型可以像普通类一样包含方法和属性。这意味着可以为枚举常量定义额外的行为和数据,从而进一步增强枚举的功能和灵活性。例如,可以为每个枚举常量定义一个返回其描述性字符串的方法。
  6. 更好的switch语句支持:在Java中,switch语句可以直接使用枚举常量作为条件表达式。这使得在处理枚举常量时,switch语句成为了一种更加自然和直观的选择。与整型或字符串相比,使用枚举作为switch语句的条件表达式可以减少错误并提高代码的可读性。
  7. 替代传统常量定义方式:在Java 1.5之前,通常使用public static final变量来定义一组常量。然而,这种方式存在类型不安全、可读性差等缺点。枚举的引入提供了一种更加优雅和类型安全的方式来替代传统的常量定义方式。

2.声明枚举

在Java中,枚举是通过enum关键字来定义的。枚举类型本质上是一种特殊的类,它继承自java.lang.Enum类(这是一个抽象类)。枚举类型的每一个实例都映射到Enum类的一个匿名子类的一个实例。

枚举的定义方式如下:

public enum Color {  
    RED, GREEN, BLUE;  
}

3.枚举类

3.1.EnumMap类

EnumMap类是Java中的一个特殊映射(Map)实现,专门用于存储键为枚举类型(Enum)的键值对。以下是关于EnumMap类的详细介绍:

3.1.1.基本概述

  • 类定义:EnumMap类位于java.util包中,它实现了Map接口,并且其键必须是枚举类型。
  • 特点
    • 高效:EnumMap在内部使用数组实现,因此其性能非常高,访问速度通常比HashMap快。
    • 枚举类型安全:由于键必须是枚举类型,这避免了类型转换错误,提高了代码的健壮性。
    • 有序性:EnumMap按照枚举类型的自然顺序(即枚举常量在枚举定义中的顺序)来存储键。
    • 低内存开销:相比于HashMap,EnumMap的内存占用更小,因为它使用紧凑的数组来存储键值对。

3.1.2.构造函数

EnumMap提供了多种构造方法来初始化映射:

  • EnumMap(Class<K> keyType):使用指定的枚举类型初始化一个空的EnumMap。
  • EnumMap(EnumMap<K,? extends V> m):使用另一个EnumMap来初始化,包括其所有键值对(如果有的话)。
  • EnumMap(Map<K,? extends V> m):使用指定的Map来初始化EnumMap,但指定的Map必须至少包含一个键值对,以便能够推断出EnumMap的键类型。

3.1.3.常用方法

EnumMap提供了Map接口中的所有方法,包括但不限于:

  • put(K key, V value):向映射中添加一个键值对。
  • get(Object key):根据键获取对应的值。
  • containsKey(Object key):检查映射中是否包含指定的键。
  • remove(Object key):根据键移除键值对。
  • size():返回映射中键值对的数量。
  • keySet():返回映射中所有键的集合。

3.1.4.使用示例

以下是一个简单的EnumMap使用示例:

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

import java.util.EnumMap;

public class EnumMapExample {
    public static void main(String[] args) {
        EnumMap<Day, String> enumMap = new EnumMap<>(Day.class);
        enumMap.put(Day.MONDAY, "Work");
        enumMap.put(Day.TUESDAY, "Gym");
        enumMap.put(Day.WEDNESDAY, "Shopping");

        String activity = enumMap.get(Day.MONDAY);
        System.out.println("Activity on Monday: " + activity);

        boolean hasMonday = enumMap.containsKey(Day.MONDAY);
        System.out.println("Contains Monday: " + hasMonday);

        enumMap.remove(Day.MONDAY);
        System.out.println("After removing Monday: " + enumMap);
    }
}

3.1.5.注意事项

  • EnumMap不是同步的。如果多个线程同时访问并修改EnumMap,则需要在外部进行同步。
  • EnumMap不允许使用null作为键,但允许使用null作为值。尝试插入null键将抛出NullPointerException。

3.2.EnumSet类

EnumSet类是Java中的一个特殊集合类,专为枚举类型设计。它实现了java.util.Set接口,但内部实现不使用常见的数据结构(如数组、链表、哈希表或红黑树),而是采用位运算来完成集合的基本操作。这使得EnumSet在处理枚举类型集合时具有非常高的效率。

3.2.1.基本特点

  1. 类型限定:EnumSet中的所有元素都必须是指定枚举类型的枚举值。
  2. 高效性:由于内部采用位运算,EnumSet在处理枚举类型集合时通常比HashSet等集合类更高效。
  3. 有序性:EnumSet中的元素按照枚举常量的声明顺序进行存储和迭代。
  4. 线程非安全:EnumSet不是线程安全的,如果多个线程同时访问并修改EnumSet,需要在外部进行同步。

3.2.2.构造方法

EnumSet是一个抽象类,不能直接使用new关键字实例化。它提供了一系列静态工厂方法来构造EnumSet实例,包括:

  • noneOf(Class<E> elementType):构造一个空的EnumSet,其元素类型为指定的枚举类型。
  • allOf(Class<E> elementType):构造一个包含指定枚举类型中所有枚举常量的EnumSet。
  • of(E e, E... elements):构造一个包含指定枚举常量的EnumSet,可以使用可变参数来指定多个枚举常量。
  • copyOf(Collection<E> c):构造一个包含指定集合中所有元素的EnumSet,要求集合c中的元素都是指定枚举类型的枚举常量。
  • copyOf(EnumSet<E> s):构造一个与指定EnumSet具有相同元素类型和集合元素的EnumSet。
  • range(E from, E to):构造一个包含从from(包含)到to(不包含)之间所有枚举常量的EnumSet。注意,这个方法要求枚举常量在声明时是有序的,并且from和to之间的枚举常量是连续的。
  • complementOf(EnumSet<E> s):构造一个包含指定枚举类型中除s集合中元素以外的所有枚举常量的EnumSet。

3.2.3.基本操作

EnumSet支持Set接口的所有基本操作,包括添加(add)、删除(remove)、检查是否包含(contains)、获取集合大小(size)等。由于内部采用位运算,这些操作的性能通常优于其他集合类。

3.2.4.集合操作

EnumSet还支持一些集合操作,如求并集(union)、交集(intersection)和补集(complement)。这些操作可以通过调用EnumSet的实例方法或使用EnumSet.copyOf等方法结合集合的addAllretainAll等方法来实现。

3.2.5.使用示例

下面是一个使用 EnumSet 的示例。首先定义一个枚举类型 Day,它包含了一周的七天。然后使用 EnumSet 来表示这一周中的特定几天。

枚举类型定义
public enum Day {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}
使用 EnumSet
import java.util.EnumSet;
import java.util.Iterator;

public class EnumSetExample {
    public static void main(String[] args) {
        // 使用 EnumSet.of() 静态方法直接初始化一个包含指定枚举常量的 EnumSet
        EnumSet<Day> weekdays = EnumSet.of(Day.MONDAY, Day.TUESDAY, Day.WEDNESDAY, Day.THURSDAY, Day.FRIDAY);

        // 遍历 EnumSet
        System.out.println("Weekdays: ");
        for (Day day : weekdays) {
            System.out.println(day);
        }

        // 添加新的元素
        weekdays.add(Day.SATURDAY);

        // 检查是否包含某个元素
        if (weekdays.contains(Day.SATURDAY)) {
            System.out.println("Weekdays now includes Saturday.");
        }

        // 移除元素
        weekdays.remove(Day.TUESDAY);

        // 使用 EnumSet.allOf() 初始化包含所有枚举常量的 EnumSet
        EnumSet<Day> allDays = EnumSet.allOf(Day.class);

        // 移除特定集合中的元素
        allDays.removeAll(weekdays);

        // 打印剩下的日子
        System.out.println("Remaining days: ");
        for (Day day : allDays) {
            System.out.println(day);
        }

        // 使用迭代器
        Iterator<Day> iterator = weekdays.iterator();
        while (iterator.hasNext()) {
            Day day = iterator.next();
            System.out.println("Iterator: " + day);
        }
    }
}

3.2.6.注意事项

  • EnumSet不允许插入null元素,如果尝试插入null元素,将抛出NullPointerException
  • 由于EnumSet的内部实现依赖于枚举常量的声明顺序和数量,因此在使用EnumSet时,需要确保枚举常量的声明顺序符合预期,并且枚举类型的元素数量不应过多(虽然Java的枚举类型在实际应用中通常不会包含过多的常量)。

4.枚举使用场景

4.1. 表示有限集合的常量

  • 颜色:在图形界面编程中,可以使用枚举来表示一组颜色,如红色、绿色、蓝色等。这样做可以确保颜色值在代码中的一致性,避免使用魔法数字(即直接使用数字表示颜色)。
  • 方向:对于游戏或其他应用程序,方向是一个常见的概念。使用枚举类型可以为每个方向指定一个常量,如东、南、西、北等。
  • 星期:在需要表示一周的每一天时,可以使用枚举。这样可以确保代码的可读性和可维护性。
  • 季节:在季节中,有显然的季节之分,使用枚举类型可以为每个季节指定一个名称,使代码变得更加直观,易于理解。

4.2. 代替常量

如果我们需要一些常量表示一个特定的状态或类型,枚举就是最好的选择。枚举本身就是常量,可以用在switch语句中,使代码更加清晰易读。

4.3. 状态或类型表示

  • 订单状态:订单可能有多个状态,如待处理、已处理、已发货、已完成等。使用枚举来表示这些状态可以确保代码的可读性和可维护性。
  • 错误代码:在许多应用程序中,错误代码是一个常见的概念。使用枚举类型可以为每个错误代码指定一个名称,使其更容易理解和处理。

4.4. 参数传递

枚举类型作为参数传递,可以缩小参数范围,从而使代码更加健壮且可读性更高。使用枚举表示的参数值受约束,这有助于防止意外的值被传入。

4.5. 配置选项

在配置系统或应用程序时,可能需要定义一组选项或设置。使用枚举可以确保这些选项的合法性,并提供类型安全的访问方式。例如,配置选项可以包括是否启用日志记录、是否禁用动画等。

4.6. 提高代码的可读性和可维护性

枚举类型的使用可以提高代码的可读性和可维护性。因为它们提供了类型安全的常量集合,并且可以与switch语句等结构一起使用,从而根据枚举值执行不同的操作。

4.7. 枚举集合(EnumSet)

EnumSet是Java中的一个类,它提供了一种比BitSet更丰富的类型安全的方式来表示一组枚举常量。使用EnumSet可以方便地进行集合操作,如添加、删除、检查是否包含某个元素等。

标签:常量,EnumSet,枚举,EnumMap,类型,Day
From: https://www.cnblogs.com/tubby233/p/18347059

相关文章

  • 枚举声明
    枚举Java枚举知识点概念enum的全称为enumeration,是JDK1.5中引入的新特性。在Java中,被enum关键字修饰的类型就是枚举类型。形式如下:enumColor{RED,GREEN,BLUE}如果枚举不添加任何方法,枚举值默认为从0开始的有序数值。以Color枚举类型举例,它的枚举常量依......
  • C语言day11(string函数族、递归函数、结构体、共用体、枚举)
    【1】string函数族1.strlen头文件:#include<string.h>格式:size_tstrlen(constchar*s);功能:计算字符串实际长度,不包括\0参数:s:目标字符串首地址返回值:字符串实际长度2.strcpy    头文件:#include<string.h>    格式:char*strcpy(char*dest,......
  • 可用于机器学习的排列组合枚举算法含passcal - c shap-c源码
    可用于机器学习的排列组合枚举算法含passcal-cshap-c源码1机器学习和数据挖掘• 特征选择:在机器学习中,需要从多个特征中选择最有价值的组合。通过枚举不同的特征组合,可以找到最佳的特征集合。• 超参数优化:在训练模型时,需要调整多个超参数。通过枚举不同的超参数组......
  • C自定义类型(结构体,联合体,枚举)详解
            在C语言中,数据类型可以分为内置类型(charshortintlongfloatdouble...)和自定义类型。内置类型是由编程语言本身定义的基本数据类型,而自定义类型是由程序员根据需要创建的数据类型。    自定义类型:  结构体,联合体(共用体),枚举。结构体:用于组......
  • 枚举
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceMR.View{classProgram{enumenXingQi{星期一=1,星期二=2,星期三=3,星期四=4,......
  • java基础6—抽象类、接口、枚举
    1.抽象类1.1简介        由于继承这个显著特点,我们可以将子类设计的更加具体,而父类更加一般化,通用化。父类可以封装不同子类的共同特征或者共同行为。而有的时候,父类中封装的方法无法具体完成子类中需要的逻辑,因此我们可以将此方法设计成抽象方法,即使用关键字abstra......
  • 枚举知识点(完结)
    枚举文章目录枚举枚举定义枚举类的实现枚举类的属性枚举类的创建创建代码常用方法枚举定义Java枚举是一个特殊类,一边表示一组常量,比如一年的4个季节,一年的12个月份,一个星期的七天,方向有东南西北等类的对象只有有限个,确定的性别:男,女枚举类的实现JDK1.5之前需要......
  • 如何定义作为函数的枚举值?
    我遇到一种情况,我需要强制并向用户提供多个选择函数之一的选项,将其作为参数传递给另一个函数:我真的想实现如下所示的功能:|||因此可以执行以下命令:fromenumimportEnum#TrivialFunction1deffunctionA():pass#TrivialFunction2deffunctionB():pass......
  • Atcoder 356 C - Keys 二进制枚举
    原题链接:https://atcoder.jp/contests/abc356/tasks/abc356_c C-Keys:问题陈述您有 N 个编号为1,2,…,N 的密钥。其中一些是真钥匙,其他都是假钥匙。有一扇门,门X,你可以插入任意数量的钥匙。只有插入至少 K 把真钥匙,X门才会打开。你已经对这些钥匙进行了 M 次......
  • C#接口,结构,枚举
    今日份主要内容:1.接口2.结构,可空类型Nullable3.新语法refstruct和refreturn4.枚举5.枚举类型作为位标志6.枚举练习,应用程序配置7.日期DateTime接口接口定义一套其它类实现它的规则。契约,一种合同。一种定义了一组相关方法、属性和事件的合同,用于实现类来遵循。接口:使......