如何使用EnumSet实现基于bit field的enum set?
来源:互联网 发布:淘宝账号被永久封号 编辑:程序博客网 时间:2024/06/06 11:38
如果我们在使用有一个枚举类型时,每次会用到其一项或多项(也就是enum set)时,会怎么做呢?
在Java没有引入EnumSet之前,有一种叫int enum pattern(assigning a different power of 2 to each constant)的做法,例如一个字体的style的枚举会写成
public static final int STYLE_BOLD = 1 << 0; // 1public static final int STYLE_ITALIC = 1 << 1; // 2public static final int STYLE_UNDERLINE = 1 << 2; // 4public static final int STYLE_STRIKETHROUGH = 1 << 3; // 8
在使用的时候,我们用按位与(|),就可以combine several constants into a set
text.applyStyles(STYLE_BOLD | STYLE_ITALIC);
不过这种做法已经是obsolete了,可以用EnumSet来替代,and it is more concise and flexible,至于效率方面,完全没有下降,因为EnumSet内部实现也是用bitwise的。
那么上面的例子就可以写成这样
// EnumSet - a modern replacement for bit fieldspublic class Text {public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }// Any Set could be passed in, but EnumSet is clearly besttext.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));}
如果我们要把这个EnumSet存储到数据库怎么办呢?其实这样的case还是挺多的,我们经常会有flag这样的column,来表示(is or is not),如果这个flag只存储一个(1 或 0 ) 虽然看起来很简单,但是很浪费而且没有扩展性,overtime,新需求也许需要个flagB, 那么你又要加一个新column,flagC,flagD.... frustrated
如果我们把EnumSet直接存到数据库,上面的问题就可以解决了,怎么存呢?看看EnumSet的源码,就知道其实它是用一个long elements来represent 这个set的, 那么我们需要写个工具类能在long和EnumSet之间做转化, 这样就可以存取数据库了。
long转EnumSet
/** * Create an enum set by parsing the specified value based on the specified enum type * * @param originalEnumType the class object of the enum type * @param elements The 2^k bit indicates the presence of the element in this set * @return */public static <T extends Enum<T>> EnumSet<T> parseEnumSet(Class<T> originalEnumType, long elements){EnumSet<T> resultEnumSet = EnumSet.allOf(originalEnumType);for (T element : resultEnumSet){if ((elements & (1L << element.ordinal())) == 0)//Check if it is 1 at bit 2^KresultEnumSet.remove(element);}return resultEnumSet;}
EnumSet转long
/** * Calculate the elements' long value from a given enum set * * @param originalEnumSet the given enum set * @return long value of elements in this set */public static <T extends Enum<T>> long getElementsValue(EnumSet<T> originalEnumSet){if (originalEnumSet == null)return 0;long elements = 0;for (T element : originalEnumSet){elements |= (1L << element.ordinal());}return elements;}
使用
//Calculate the long value before storing in DBSystem.out.println(EnumSetUtil.getElementsValue(EnumSet.of(Style.BOLD, Style.TEST, Style.UNDERLINE)));//Parse the enum set from long value after fetching from DBSystem.out.println(EnumSetUtil.parseEnumSet(Style.class, 10));
- 如何使用EnumSet实现基于bit field的enum set?
- Enum和EnumSet的使用
- 熟练使用java的Enum、EnumSet、EnumMap
- Java中Enum、EnumMap、EnumSet使用示例
- Enum、EnumMap、EnumSet的用法讲解
- Enum、EnumMap、EnumSet的用法讲解
- EnumSet 的一般使用
- enum,EnumMap,EnumSet
- 枚举:集合对enum的支持,EnumSet,EnumMap
- Java Enum、EnumMap、EnumSet 详解
- poj1250基于enum较简单的实现
- 转 -- 浅析 MySQL int char bit set enum 的优劣与运用
- Bit field
- Bit field
- 14. JAVA 枚举(Enum、类集EnumMap&EnumSet 、实现接口、定义抽象方法) ----- 学习笔记
- 数据库使用中出现的错误(enum、set)
- 使用attribute + 扩展方法完成 enum中field的信息映射
- Java enum enumset enummap的详解(记性不好就多动笔)
- 修改hosts文件无效解决办法
- VS 2010编译Gh0st 3.6
- Retrieving Media from a Content Resolver
- 借船过河:一个据说能看穿你的人性和欲望的心理测试
- window.open居中显示,模式窗口
- 如何使用EnumSet实现基于bit field的enum set?
- tyvj-1144 股票 DP
- Android系列教程之七:EditText使用详解-包含很多教程上看不到的功能演示
- 通过帧标签获取对应的帧
- 不要在功能上竞争
- 移植ads7846驱动到tiny6410(tiny6410)
- ubuntu 11.10 中eclipse 修改代码悬浮提示窗口颜色
- java文件操作
- wdk 编译《windows驱动开发技术详解》中的示例