Example7.java
public class Example7
{
public static void main(String[] args)
{
int myFavoriteFoods = OldFoods.Pasta | OldFoods.Hamburger | OldFoods.Bread | OldFoods.Rice;
boolean answer = (myFavoriteFoods & OldFoods.Fruit) != 0;
System.out.printf("Do you like eat fruit? %s\n", answer?"Yes":"No");
answer = (myFavoriteFoods & OldFoods.Hamburger) != 0;
System.out.printf("Do you like eat hamburger? %s\n", answer?"Yes":"No");
}
}
class OldFoods
{
public static final int Fruit = 0x01;
public static final int Rice = 0x02;
public static final int Noodles = 0x04;
public static final int Hamburger = 0x08;
public static final int Pasta = 0x10;
public static final int Cake = 0x20;
public static final int Bread = 0x40;
}
在上面的程序里声明了7个int变量,分别表示刚刚所说的水果(Fruit)、米饭(Rice)、面条(Noodles)、汉堡(Hamburger)、意大利面(Pasta)、蛋糕(Cake)和面包(Bread),然后它们的值分别用十六进位来表示,换算回十进位的话分别是1、2、4、8、16、32、64。接下来我们所要做的事,就是把自己喜欢的食物组合起来,然后问问看哪些食物是你喜欢的,哪些有时不喜欢的。
到目前为止看起来很不错,不过这种方式隐含了几个问题:第一,如果今天食物的选项有很多很多,超过64种的话,那就不能使用这个算法了。因为刚刚我们所使用的技巧是使用二的倍数来表示每个值,目前Java最大的整数是2的63次方减1,所以就不够用了。第二,使用上不方便。
下面用EnumSet类来解决这些问题:
18-NewFoods.java
package java2.E;
public enum NewFoods
{
Fruit,
Rice,
Noodles,
Hamburger,
Pasta,
Cake,
Bread
}
19-EnumSetExample.java
package java2.E;
import java.util.*;
import static java2.E.NewFoods.*;
public class EnumSetExample
{
public static void main(String[] args)
{
EnumSet<NewFoods> myFavoriteFoods = EnumSet.of(Pasta, Hamburger, Bread, Rice);//010
boolean answer = myFavoriteFoods.contains(Fruit);//012
System.out.printf("Do you like eat fruit? %s\n", answer?"Yes":"No");
answer = myFavoriteFoods.contains(Hamburger);//014
System.out.printf("Do you like eat hamburger? %s\n", answer?"Yes":"No");
System.out.print("My favorite foods are ");
for(NewFoods food : myFavoriteFoods)
System.out.printf("%s, ", food);
System.out.println();
}
}
程序19的第10行,我们调用EnumSet的of方法,把那四样食物给传进去,然后我们会得到一个EnumSet类的对象。今天你喜欢三样就传入三样食物的枚举类型值,喜欢五样就传五样。全都喜欢,我们可以改用另外一个方法“allOf”,这个方法需要一个参数,跟EnumMap类的构造函数一样,需要传入该Enum枚举类型的类,以这个范例来说就是传入“NewFoods.class”。
Enumset Fonds=Enumset.allof(New Foods.class);
EnumSet也跟Collection API里面的Set一样,拥有相同的操作方式,你要判断里面有没有包含哪个值,就用“contains”方法,例如程序19的第12和14行。我们还可以使用for-each循环或是Iterator来把该EnumSet对象里的数据全都给捉出来。
如果今天你除了水果和意大利面之外,其他通通都喜欢,那可以先产生一个只有面跟意大利面的EnumSet对象,然后使用“complementOf”方法,把这个对象传进去,就可以得到除了这两样食物之外,包含其他食物的EnumSet对象了。
EnumSet set1 = EnumSet.of(Noodles, Pasta);
EnumSet set2 = EnumSet.complement(set1);
如果你全都不喜欢,可以使用“noneOf”方法,一样传入一个Enum枚举类型的类给它,它就会给你一个空的EnumSet对象。
EnumSet empty = EnumSet.noneof(NewFoods.class)
如果你只想要第2样到第5样食物,除了一一把它们当参数传入之外,还可以使用“range”方法。它需要两个参数,就是你把头尾给传进去就行。
EnumSet set1 = EnumSet.of(Rice,Noodles,Hamburger,Pasta);
或
EnumSet set2 = EnumSet.range(Rice,Pasta);
如果你想要复制一个一摸一样的EnumSet对象,可以使用“clone”方法。
EnumSet set3 = set1.clone();
如果你想要从别的Collection对象或是EnumSet对象复制数据过来,可以使用“copyOf”方法。
EnumSet set4 = EnumSet.copyOf(set1);
EnumSet类大致上就提供了这些方法,除了clone方法之外,其他的都是类方法,所以可以直接从EnumSet类来调用使用。另外EnumSet跟EnumMap一样,同一个EnumSet对象只能包含同一Enum枚举类型的值。