跟我学(Effective Java 2)第32条:用EnumSet代替位域

第32条:用EnumSet代替位域

如果一个枚举类型的元素主要用在集合中,一般使用int枚举模式,将2的不同倍数赋予每个常量:

public class Text {
    public static final int STYLE_BOLD = 1 << 0;
    public static final int STYLE_ITALIC = 1 << 1;
    public static final int STYLE_UNDERLINE = 1 << 2;
    public static final int STYLE_STRIKETHROUGH = 1 << 3;
    
    public void applyStyles(int styles) {
        ...
    }
}

这种表示法让你用OR位运算将几个常量合并到一个集合中,称作位域(bit field):

text.applyStyles(STYLE_BOLD | STYLE_ITALIC);

位域表示法也允许利用位操作,有效地执行像union(联合)和intersection(交集)这样的集合操作。但位域有着int枚举常量的所有缺点,甚至更多。当位域以数字形式打印时,翻译位域比翻译简单的int枚举常量要困难得多。甚至,要遍历位域表示的所有元素也没有很容易的方法。

java.util包提供了EnumSet类来有效地表示从单个枚举类型中提取多个值的多个集合,这个类实现Set接口,提供丰富的功能、类型安全性,以及可以从任何其他Set实现中得到的互用性。

public class Text{

	public enum Style{
		BOLD,ITALIC,UNDERLINE,STRIKETHROUGH
	}
	
	public void applyStyles(Set<Style> styles){
		...
	}
}

客户端代码

text.applyStyles(EnumSet.of(Style.BOLD,Style.ITALIC));

总之:正是因为枚举类型要用在集合(Set)中,所以没有理由用位域来表示它.EnumSet类集位域的简洁和性能的优势及枚举类型的所有优点与一身.实际上EnumSet也有个缺点,即它无法创建不可变的EnumSet(Java1.6为止没有解决).同时,可以用Collections.unmodifiable将EnumSet封装起来,但是间接性和性能会受到影响。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值