博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java中使用 Long 表示枚举类
阅读量:6340 次
发布时间:2019-06-22

本文共 2572 字,大约阅读时间需要 8 分钟。

在日常的开发过程中,很多时候我们需要枚举类(enum)来表示对象的各种状态,并且每个状态往往会关联到指定的数字,如:

    private enum Color {        RED(11), GREEN(21), YELLOW(31), BLACK(160);		...    };

或者用枚举类来表示一系列状态的转变关系:

    enum Week{        SUNDAY(1), MONDAY(2), TUESDAY(3), WEDNESDAY(4), THRUSDAY(5), FRIDAY(6), SATRUDAY7);		...    };

那么,如何用最少的存储来实现这类需求,答案很简单,位存储。如 1bit 表示 0,1 两种状态,2bit 表示 00,01,10,11 四种状态,所以我们可以用一个 long 类型(64bit)/int 类型(32bit)存储多种状态,如下图:

 

enter description here

 

位存储示例

 

但是每新建一个枚举类都需要自己操作 bit

  1. 导致程序不易理解

  2. 容易出错,耗费精力

Hadoop hdfs 的实现中,也遇到类似的问题,它借助于 LongBitFormat.java 类封装了 bit 操作:

    public class LongBitFormat implements Serializable {    private static final long serialVersionUID = 1L;    private final String NAME;    /** Bit offset */    private final int OFFSET;    /** Bit length */    private final int LENGTH;    /** Minimum value */    private final long MIN;    /** Maximum value */    private final long MAX;    /** Bit mask */    private final long MASK;    public LongBitFormat(String name, LongBitFormat previous, int length,                         long min) {        NAME = name;        OFFSET = previous == null ? 0 : previous.OFFSET + previous.LENGTH;        LENGTH = length;        MIN = min;        MAX = ((-1L) >>> (64 - LENGTH));//移动的位数,右移64-Leng位,相当于保留length位        MASK = MAX << OFFSET;    }    /** Retrieve the value from the record. */    public long retrieve(long record) {        return (record & MASK) >>> OFFSET;    }    /** Combine the value to the record. */    public long combine(long value, long record) {        if (value < MIN) {            throw new IllegalArgumentException(                    "Illagal value: " + NAME + " = " + value + " < MIN = " + MIN);        }        if (value > MAX) {            throw new IllegalArgumentException(                    "Illagal value: " + NAME + " = " + value + " > MAX = " + MAX);        }        return (record & ~MASK) | (value << OFFSET);    }    public long getMin() {        return MIN;    }}

当然,你也可以实现 IntBigFormat,ShortBitFormat 等

首先分析该类的构造方法:

        NAME = name;        OFFSET = previous == null? 0: previous.OFFSET + previous.LENGTH;        LENGTH = length;        MIN = min;        MAX = ((-1L) >>> (64 - LENGTH));//移动的位数,右移64-Leng位,相当于保留length位        MASK = MAX << OFFSET;

字段:
NAME:状态名,可自定义

OFFSET:该状态在 long 字节中的偏移

LENGTH:用多少位存储该状态关联的数字

MIN:该状态关联的最小值

MAX:该状态关联的最大值

MASK:掩码,(OFFSET~OFFSET+LENGTH - 1) == 1

类方法:
retrieve(long record):获得该状态关联的数字

combine(long value, long record):将一个 value 加到 record 中,例如:将 value 值对应的枚举类存储在 32-40,则先将32-40bits 清零,再将value 对应的二进制加入到 32-40

那么如何使用该类:

 

}

本文转自lzwxx 51CTO博客,原文链接:

http://blog.51cto.com/13064681/1943402

转载地址:http://neeoa.baihongyu.com/

你可能感兴趣的文章
[20160816]du 显示各个目录使用情况.txt
查看>>
拥有高水平热稳定性的红外传感器 可用于精确温度测量的多种应用
查看>>
WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox
查看>>
数据库引擎调整顾问
查看>>
Enhancing the Application: Advanced JDBC Features(转)
查看>>
Replication的犄角旮旯(五)--关于复制identity列
查看>>
5-关联模型
查看>>
Android零基础入门第35节:Android中基于回调的事件处理
查看>>
nagios报错一例
查看>>
初识servlet
查看>>
微信小程序开发(5) 2048游戏
查看>>
2017年第二季度全球科技公司IPO报告出炉,两年来科技IPO最好的一季
查看>>
脚本操作zk
查看>>
机器学习-线性回归-多维度特征变量
查看>>
H.264 基础及 RTP 封包详解
查看>>
用心设计的艺术
查看>>
【翻译】Ext JS 5的平板支持
查看>>
java获取程序执行时间
查看>>
怎么输入MathType不等号
查看>>
day5:python学习之集合
查看>>