82. 枚举

枚举类是一种很实用的类型,在标识状态一类的应用中,使用起来十分方便。当然我们也可以用map来替代枚举类型的功能,虽然简单,但是阅读起来map要比枚举稍微差一些,可以根据情况来选择。

map

比较清晰的直接赋值为一个map形式。

package github.banana;

import java.util.HashMap;
import java.util.Map;

/**
 * 供应商类型和描述
 */
public class TP {

    public static String getName(String id) {
        Map<String, String> map = new HashMap<>();
        map.put("1", "携程");
        map.put("2", "国航");
        map.put("4", "东航");
        map.put("8", "南航");
        map.put("16", "携程一期H5");
        map.put("32", "必去");
        map.put("64", "携程H5抓取");
        map.put("128", "必去国际");
        map.put("256", "就旅行");
        map.put("512", "必去候补");
        map.put("1024", "去哪儿");
        map.put("2048", "携程H5阿拉丁");
        map.put("ctrip", "携程");

        return map.getOrDefault(id, "未知");
    }
}

使用枚举来实现。

package github.banana;

/**
 * 供应商类型和描述
 */
public enum  EnumTP {
    CTRIP("1", "携程"),
    CA("2", "国航"),
    MU("4", "东航"),
    CZ("8", "南航"),
    CTRIPH5("16", "携程一期H5"),
    BIQU("32", "必去"),
    CTRIPCRAWL("64", "携程H5抓取"),
    BIQUINT("128", "必去国际"),
    BIQUSTANDARD("256", "就旅行"),
    QUNAR("512", "去哪儿"),
    CTRIPHTALADDIN("1024", "携程H5阿拉丁"),
    CTRIPV2("ctrip", "携程");

    // 供应商标识
    private String index;

    // 供应商描述
    private String name;

    EnumTP(String index, String name) {
        this.index = index;
        this.name = name;
    }

    // 获取供应商中文名称
    public static String getName(String index) {
        for (EnumTP enumTP:EnumTP.values()) {
            if (index.equals(enumTP.index)) {
                return enumTP.name;
            }
        }
        return "未知";
    }
}

可以看出,如果操作本身比较简单,其实选择哪一种都是比较合乎逻辑的。但就是设计来说,map因数据结构的关系,理论上会更快一些,如果做持久化后。不过这些性能,可能并不明显。

package github.banana;

public class TPTest {

    public static void main(String[] args) {
        String partner = "256";

        System.out.println(TP.getName(partner));

        System.out.println(EnumTP.getName(partner));
    }
}

单一枚举

功能比较单一的枚举,比如状态的描述等。

package github.banana;

/**
 * 定义一个枚举类
 */
public enum  EnumTest {

    // 枚举类内容, 通常由大写字母标识, 每个枚举类型的说明直接写在括号中
    A("字母A"), B("字母B"), C("字母C"), D("字母D");

    // 枚举类型的说明
    private String index;

    // 枚举类型说明的赋值, 该修饰符默认是private, 不允许其他类型修饰符
    EnumTest(String index) {
        this.index = index;
    }

    // 前端直接通过该公开方法获取枚举类型的值
    public String getIndex() {
        return index;
    }
}

访问也很简单。

package github.banana;

public class EnumTestCase {

    public static void main(String[] args) {

        // 遍历枚举类型的标识
        for (EnumTest enumTest : EnumTest.values()) {
            System.out.println(enumTest.name());
        }

        // 获取枚举类型的描述
        System.out.println(EnumTest.A.getIndex());
    }
}

复合枚举

稍微复杂一点的枚举类型,可以操作范围等。

package github.banana;

/**
 * 范围类型枚举
 */
public enum EnumRange {

    // 定义枚举类型所属的范围
    PC(100, 500), WISE(501, 1000);

    // 范围的起止
    private int start;
    private int end;

    EnumRange(int start, int end) {
        this.start = start;
        this.end = end;
    }

    // 判断是否在该范围内
    public static EnumRange getDesc(int index) {
        for (EnumRange enumRange : EnumRange.values()) {
            if (index >= enumRange.start && index <= enumRange.end) {
                return enumRange;
            }
        }
        throw new IndexOutOfBoundsException("未知的范围");
    }

    // 也可以实现各种枚举类型的具体判断, 比如PC
    public boolean isPC(int index) {
        return index >= PC.start && index <= PC.end;
    }

    public boolean isWISE(int index) {
        return index >= WISE.start && index <= WISE.end;
    }
}

也是直接使用。

package github.banana;

public class EnumRangeCase {

    public static void main(String[] args) {
        // 指定一个范围具体值
        int index = 120;
        EnumRange enumRange = EnumRange.getDesc(index);

        // 判断属于何种类型
        System.out.println(enumRange.name());

        // 是否属于PC
        System.out.println(EnumRange.PC.isPC(index));

        // 是否属于WISE
        System.out.println(EnumRange.WISE.isWISE(index));
    }
}