java的比特位枚举
来源:互联网 发布:机房网络应急预案 编辑:程序博客网 时间:2024/03/29 17:17
原文见:http://eddmann.com/posts/using-bit-flags-and-enumsets-in-java/
今天想在java里面使用比特位的枚举,想达到C语言中的文件打开类型:APPEND | WRITE这样的效果。
之前写C#找到过Flag和这类似,不知道java里面如何写,百度了好久找到一篇不错的文章。
好容易看懂,直接转过来了!
Using Bit Flags and EnumSets in Java
20 Dec 2013Bit Flags
Bit flags, commonly referred to as Bit fields are an efficient way of storing several related boolean values in a single primitive type. Internally represented in binary, you can decide on how large the storage type needs to be - for example, a Java integer will provide you with space for 31 flags. Being a 32 bit type you would assume to have access to this many flags, however, due to it being a signed value the most significant bit is reserved to store its +/- sign.
Flags are typically stored as public constants within the related class, for example, the Pattern class includes the flags ‘CASE_INSENSITIVE’ and ‘MULTILINE’ to alter match criteria. Setting the values as incremental powers of 2 allows the user to compose multiple constants together using the | (OR) operator to achieve the desired flag combination. The implementer is then able to base the methods execution on the passed in flags by checking for presence of the constant value using the & (AND) operator as a bit mask. This idea can be more meaningfully described using the example below.
public static final int UPPERCASE = 1; // 0001public static final int REVERSE = 2; // 0010public static final int FULL_STOP = 4; // 0100public static final int EMPHASISE = 8; // 1000public static final int ALL_OPTS = 15; // 1111public static String format(String value, int flags){ if ((flags & UPPERCASE) == UPPERCASE) value = value.toUpperCase(); if ((flags & REVERSE) == REVERSE) value = new StringBuffer(value).reverse().toString(); if ((flags & FULL_STOP) == FULL_STOP) value += "."; if ((flags & EMPHASISE) == EMPHASISE) value = "~*~ " + value + " ~*~"; return value;}
As you can see, I have defined 5 different constants all with specific values that correspond to different binary representations. In regard to the final constant which I set to the decimal 15, in essence this fills in all of the previously created value combinations. Within the method block I check for presence of each flag by masking the ‘flags’ parameter with the constant value. If the resulting value is equal to the specified constant we can then act on this condition.
format("Joe", UPPERCASE); // JOEformat("Joe", REVERSE); // eoJformat("Joe", FULL_STOP | EMPHASISE); // ~*~ Joe. ~*~format("Joe", ALL_OPTS); // ~*~ EOJ. ~*~
Above are a few examples of the method being used in multiple ways. The third example shows the ability of composing values from multiple flags (binary representation 1100).
EmunSets
Traditional use of bit flags has been around for many years and are a very performant storage mechanism (especially in graphic rendering). However, it can be very easy for the resulting code to be hard to understand. Another glaring issue is that they are not type safe, nullifying the benefits of having a type system put in place. EnumSets however have the efficiency of bit flags, but without the loss of safety the the type system provides. I should point out that there is another Set implementation called BitSet which provides similar functionality. It is recommended that if you desire a flagging system such as the use-case described an EnumSet will provide you with the best results.
public enum Flag { UPPERCASE, REVERSE, FULL_STOP, EMPHASISE; public static final EnumSet<Flag> ALL_OPTS = EnumSet.allOf(Flag.class);}
public static String format(String value, EnumSet<Flag> flags){ if (flags.contains(Flag.UPPERCASE)) value = value.toUpperCase(); if (flags.contains(Flag.REVERSE)) value = new StringBuffer(value).reverse().toString(); if (flags.contains(Flag.FULL_STOP)) value += "."; if (flags.contains(Flag.EMPHASISE)) value = "~*~ " + value + " ~*~"; return value;}
In the case of an EnumSet you must first define your enumerated type, which encapsulates all the desired constants. Similar to how I defined the ‘ALL_OPTS’ constant in the first example, I have created a EnumSet consisting of all constants in the Flag type. EnumSet implements the Set interface, so you can use it as you would a typical set, calling ‘contains’ on it to query presence of a certain flag.
format("Sally", EnumSet.of(Flag.UPPERCASE)); // SALLYformat("Sally", EnumSet.of(Flag.REVERSE)); // yllaSformat("Sally", EnumSet.of(Flag.FULL_STOP, Flag.EMPHASISE)); // ~*~ Sally. ~*~format("Sally", Flag.ALL_OPTS); // ~*~ YLLAS. ~*~
Above are a few examples of using the EnumSet in place of a typical bit flag system. As you can see, we are able to complete all the examples that were possible in the previous use-case, but this time it is more readable and we are less prone to error.
- java的比特位枚举
- 置位比特位置查找java
- 枚举的位运算
- 枚举的位运算
- 8位字节的比特翻转
- 翻转无符号整数的比特位
- c语言实现比特位的逆转
- 计算两个数的不同比特位
- 写一个宏函数交换一个数字的偶数比特位和奇数比特位
- 指针,比特位操作
- 颠倒比特位
- Android(Java):c枚举,位运算
- Java 枚举--枚举的作用
- 采用比特位运算改进的N皇后算法
- 字节、字、位、比特,这四者之间的关系
- 字节、字、位、比特,四者之间的关系
- 统计无符号整数比特位为1的数量
- 第二周作业---二进制数的比特位
- HTML之JavaScript基础知识
- 前端网老姚浅谈:怎么学JavaScript?
- log4j有关
- React Native 项目常用第三方组件汇总
- 问题1:数据库选型
- java的比特位枚举
- 秒杀抢购思路以及高并发下数据安全
- 秒杀抢购思路以及高并发下数据安全
- 外键创建失败原因
- PL/SQL解析中文
- 通过node操作MongoDB数据库
- Android Matrix.mapRect 方法讲解
- iOS清除UserDefaults存储空间
- 初学java:生产者与消费者随机多数量生产与消费