zoukankan      html  css  js  c++  java
  • K:java中枚举的常见用法

    用法一:常量

      在JDK1.5 之前,我们定义常量都是: public static fianl....。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。

    public enum Color {  
          RED, GREEN, BLANK, YELLOW  
        }  
    

    用法二:switch

      JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。

    enum Signal {  
        GREEN, YELLOW, RED  
    }  
    public class TrafficLight {  
        Signal color = Signal.RED;  
        public void change() {  
            switch (color) {  
            case RED:  
                color = Signal.GREEN;  
                break;  
            case YELLOW:  
                color = Signal.RED;  
                break;  
            case GREEN:  
                color = Signal.YELLOW;  
                break;  
            }  
        }  
    }  
    

    用法三:向枚举中添加新方法

      如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且Java要求必须先定义enum实例。

    public enum Color {  
            RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);  
            // 成员变量  
            private String name;  
            private int index;  
            // 构造方法  
            private Color(String name, int index) {  
                this.name = name;  
                this.index = index;  
            }  
            // 普通方法  
            public static String getName(int index) {  
                for (Color c : Color.values()) {  
                    if (c.getIndex() == index) {  
                        return c.name;  
                    }  
                }  
                return null;  
            }  
            // get set 方法  
            public String getName() {  
                return name;  
            }  
            public void setName(String name) {  
                this.name = name;  
            }  
            public int getIndex() {  
                return index;  
            }  
            public void setIndex(int index) {  
                this.index = index;  
            }  
        }  
    

    用法四:覆盖枚举的方法

    下面给出一个toString()方法覆盖的例子。

    public enum Color {  
            RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);  
            // 成员变量  
            private String name;  
            private int index;  
            // 构造方法  
            private Color(String name, int index) {  
                this.name = name;  
                this.index = index;  
            }  
            //覆盖方法  
            @Override  
            public String toString() {  
                return this.index+"_"+this.name;  
            }  
        }  
    

    用法五:实现接口

      所有的枚举都继承自java.lang.Enum类。由于Java不支持多继承,所以枚举对象不能再继承其他类。

    public interface Behaviour {  
            void print();  
            String getInfo();  
        }  
        public enum Color implements Behaviour{  
            RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);  
            // 成员变量  
            private String name;  
            private int index;  
            // 构造方法  
            private Color(String name, int index) {  
                this.name = name;  
                this.index = index;  
            }  
        //接口方法  
            @Override  
            public String getInfo() {  
                return this.name;  
            }  
            //接口方法  
            @Override  
            public void print() {  
                System.out.println(this.index+":"+this.name);  
            }  
        }  
    

    用法六:使用接口组织枚举

    public interface Food {  
            enum Coffee implements Food{  
                BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO  
            }  
            enum Dessert implements Food{  
                FRUIT, CAKE, GELATO  
            }  
        }  
    

    用法七:关于枚举集合的使用

    如下内容有用到的代码:

    public enum EnumTest01 {  
          
        UPDATE(1,"更新"),QUERY(2,"查询"),DELETE(3,"删除");  
        private Integer enumValue;  
        private String enumDesc;  
          
        private EnumTest01(Integer enumValue, String enumDesc) {  
            this.enumValue = enumValue;  
            this.enumDesc = enumDesc;  
        }  
          
        public int getEnumValue(){  
            return this.enumValue;  
        }  
          
        public String getEnumDesc(){  
            return this.enumDesc;  
        }  
    }  
    

    EnumMap

      Map的实现类有很多种,EnumMap从名字我们可以看出这个Map是给枚举类用的。它的key为枚举元素,value自定义。在工作中我们也可以用其他的Map来实现我们关于枚举的需求,但是为什么要用这个EnumMap呢?因为它的性能高!为什么性能高?因为它的内部是用数组的数据结构来维护的!我们可以看一下它的源码实现:

    put方法

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

      typeCheck是用来检查key的类型的,因为key只能为枚举元素。接下来的这一句int index = key.ordinal(); key.ordinal()这个就是我们上面说的枚举类型的序号,然后被当做数组的下标,放到vals这个数组里。那么get方法呢?

    get方法

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

    注意这一句话:vals[((Enum<?>)key).ordinal()]。这个不就是取得下标,根据下标获取数组中的值吗?!

    remove方法

    public V remove(Object key) {  
            if (!isValidKey(key))  
                return null;  
            int index = ((Enum<?>)key).ordinal();  
            Object oldValue = vals[index];  
            vals[index] = null;  
            if (oldValue != null)  
                size--;  
            return unmaskNull(oldValue);  
        }  
    

    remove方法的实现也是挺简单的,就是把相应下标的元素变为null,等着GC回收。

    EnumSet

      EnumSet这是一个用来操作Enum的集合,是一个抽象类,它有两个继承类:JumboEnumSet和RegularEnumSet。在使用的时候,需要制定枚举类型。它的特点也是速度非常快,为什么速度很快呢?因为每次add的时候,每个枚举值只占一个长整型的一位。我们可以翻看源码来看看它的实现:

    add方法

    public boolean add(E e) {  
        typeCheck(e);  
      
        long oldElements = elements;  
        elements |= (1L << ((Enum<?>)e).ordinal());  
        return elements != oldElements;  
    }  
    

    从中我们可以看出是先对一个长整型左移枚举类型的序列数,然后再和长整型 或 。
    ps:其中值得我们引起注意的代码的实现是1L<<((Enum<?>)e).ordinal());这段代码,其实现了每个元素仅占一位的效果。

    of方法

    of方法有好几个重载的方法,它的作用是创建一个最初包含指定元素的枚举 Set。

    EnumSet<EnumTest01> enumSets = EnumSet.of(EnumTest01.DELETE);  
    

    allOf

    创建一个包含指定元素类型的所有元素的枚举 Set。

    EnumSet<EnumTest01> enumSets = EnumSet.allOf(EnumTest01.class);  
    

    range方法

    创建一个指定范围的Set。

    EnumSet<EnumTest01> enumSets = EnumSet.range(EnumTest01.DELETE,EnumTest01.UPDATE);  
    

    noneOf方法

    创建一个指定枚举类型的空set。

    EnumSet<EnumTest01> enumSet = EnumSet.noneOf(EnumTest01.class);  
    enumSet.add(EnumTest01.DELETE);  
    enumSet.add(EnumTest01.UPDATE);  
    for (Iterator<EnumTest01> it = enumSet.iterator(); it.hasNext();) {  
        System.out.println(it.next().getEnumDesc());  
    }  
    for (EnumTest01 enumTest : enumSet) {  
        System.out.println(enumTest.getEnumDesc() + "  ..... ");  
    }  
    

    copyOf方法

    创建一个set的并copy所传入的集合中的枚举元素。

    EnumSet<EnumTest01> enumSets = EnumSet.copyOf(enumSet);  
    

    回到目录|·(工)·)

  • 相关阅读:
    How to function call using 'this' inside forEach loop
    jquery.validate.unobtrusive not working with dynamic injected elements
    Difference between jQuery.extend and jQuery.fn.extend?
    Methods, Computed, and Watchers in Vue.js
    Caution using watchers for objects in Vue
    How to Watch Deep Data Structures in Vue (Arrays and Objects)
    Page: DOMContentLoaded, load, beforeunload, unload
    linux bridge
    linux bridge
    EVE-NG网卡桥接
  • 原文地址:https://www.cnblogs.com/MyStringIsNotNull/p/8018189.html
Copyright © 2011-2022 走看看