`
bingooh
  • 浏览: 53267 次
  • 性别: Icon_minigender_1
  • 来自: 佛山
社区版块
存档分类
最新评论

6.33 使用EnumMap替代使用枚举量的ordinal做索引

 
阅读更多

假设有如下类Food(食物),枚举类Type定义Food的类型:

public class Food {
	public enum Type{FRUIT,VEGETABLE}
	
	private final Type type;
	private final String name;
	
	public Food(String name,Type type){
		this.name=name;
		this.type=type;
	}
	
	public String getName(){
		return name;
	}
	
	public Type getType(){
		return type;
	}
}

 

以下数组包含了多种食物,如下:

	private Food[] foods;
	
	@BeforeClass
	public void init(){
		Food apple=new Food("apple",Type.FRUIT);
		Food pear=new Food("pear",Type.FRUIT);
		Food cabbage=new Food("cabbage",Type.VEGETABLE);
		Food potato=new Food("potato",Type.VEGETABLE);
		
		foods=new Food[]{apple,cabbage,pear,potato};
	}

 

假设现在需要根据Food类型对其进行分类,把相同类型的Food放入同一个HashSet对象里,其中一种做法如下:

	@Test
	public void testFood(){
		//根据Food类型分类,存放到相应的Set里
		Set<Food>[] foodsByType=new Set[Type.values().length];
		
		for(int i=0,len=foodsByType.length;i<len;i++)
			foodsByType[i]=new HashSet<Food>();
		
		for(Food food:foods){
			//使用了Type枚举量的ordinal()作为索引值,取出相应的Set对象
			foodsByType[food.getType().ordinal()].add(food);
		}
		
		for(Type type:Type.values()){
			Set<Food> foods=foodsByType[type.ordinal()];
			
			for(Food food:foods)
				Assert.assertEquals(food.getType(), type);
		}
	}

 

以上代码其中一个缺点是只能使用int类型的索引值从数组里取出相应的HashSet对象,可能导致ArrayIndexOutOfBoundsException异常。另一种更好的做法如下:

	@Test
	public void testFoodMap(){
		Map<Type, Set<Food>> foodsByType=new EnumMap<Food.Type, Set<Food>>(Type.class);
		
		for(Type type:Type.values())
			foodsByType.put(type, new HashSet<Food>());
		
		//使用Type枚举量做为key值
		for(Food food:foods)
			foodsByType.get(food.getType()).add(food);

		for(Type type:Type.values()){
			Set<Food> foods=foodsByType.get(type);
			
			for(Food food:foods)
				Assert.assertEquals(food.getType(), type);
		}
	}

 

以上代码EnumMap使用枚举量Type作为key,因此更不容易出错。EnumMap底层使用数组维护key,因此与第一种做法在性能上相差无几。

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics