Java 处理布尔标志的最佳方法
有一种情况是,我需要在代码中维护许多布尔标志 情况如下- 我现在有6面旗子,旗子1,旗子2,旗子3,旗子4,旗子5,旗子6 这些标志在程序中切换。现在,这些标志可能会增加,我不喜欢有这么多标志的代码 我曾想过在嵌套类中使用布尔数组,类似这样-Java 处理布尔标志的最佳方法,java,Java,有一种情况是,我需要在代码中维护许多布尔标志 情况如下- 我现在有6面旗子,旗子1,旗子2,旗子3,旗子4,旗子5,旗子6 这些标志在程序中切换。现在,这些标志可能会增加,我不喜欢有这么多标志的代码 我曾想过在嵌套类中使用布尔数组,类似这样- private static class Flag{ private static boolean[] flags = new boolean[]{false,false,false,false,false,false,false};
private static class Flag{
private static boolean[] flags = new boolean[]{false,false,false,false,false,false,false};
private static void enableFlag1(){
flags[0] = true;
}
private static void disableFlag1(){
flags[0] = true;
} //... So on for each flag
}
但在这里,我必须为每个标志编写方法。我喜欢这种方法,因为它将用户从内部布尔数组表示中抽象出来,因此标志较少,但对于许多标志来说,这似乎是一个问题。
请协助说明最好的方法是什么?您可以使用
枚举集是使用枚举的ordinal()
值在长数组中内部实现的位,该值非常有效,使其具有与的类似的性能特征,但具有更高的类型安全性和更清晰的可读性
例如,给定此枚举:
enum Features {
FEATURE1, FEATURE2, FEATURE3
}
您可以创建具有适当标志的枚举集,如下所示:
Set<Features> flags = EnumSet.of(FEATURE1);
或者,对于多个测试,您可以将其与第二组进行比较:
Set<Features> requiredFlags = EnumSet.of(FEATURE1, FEATURE2);
flags.containsAll(requiredFlags); // false
Set<Features> allFlags = EnumSet.allOf(Features.class);
allFlags.containsAll(requiredFlags); // true
<>但是,考虑它们是不可变的通常是个好主意,甚至可能在调用< /p>时把它们包起来。
由于EnumSet
的行为类似于常规集,因此对其执行集合操作可以很好地表达成员关系、并集、交集和差分关系。为此,可以使用
枚举集是使用枚举的ordinal()
值在长数组中内部实现的位,该值非常有效,使其具有与的类似的性能特征,但具有更高的类型安全性和更清晰的可读性
例如,给定此枚举:
enum Features {
FEATURE1, FEATURE2, FEATURE3
}
您可以创建具有适当标志的枚举集,如下所示:
Set<Features> flags = EnumSet.of(FEATURE1);
或者,对于多个测试,您可以将其与第二组进行比较:
Set<Features> requiredFlags = EnumSet.of(FEATURE1, FEATURE2);
flags.containsAll(requiredFlags); // false
Set<Features> allFlags = EnumSet.allOf(Features.class);
allFlags.containsAll(requiredFlags); // true
<>但是,考虑它们是不可变的通常是个好主意,甚至可能在调用< /p>时把它们包起来。
由于
EnumSet
的行为与常规集合类似,因此对其执行集合操作可以很好地表达成员关系、并集、交集和差异关系。一种解决方案是使用映射在单个集合中命名标志。e、 g
Map<String, Boolean> flags = new HashMap<>();
flags.put("flagName1", true);
flags.put("flagName2", false);
boolean flag1 = flags.get("flagName1");
Map flags=newhashmap();
flags.put(“flagName1”,true);
flags.put(“flagName2”,false);
布尔flag1=flags.get(“flagName1”);
一种解决方案是使用地图在单个集合中命名您的标志。e、 g
Map<String, Boolean> flags = new HashMap<>();
flags.put("flagName1", true);
flags.put("flagName2", false);
boolean flag1 = flags.get("flagName1");
Map flags=newhashmap();
flags.put(“flagName1”,true);
flags.put(“flagName2”,false);
布尔flag1=flags.get(“flagName1”);
对于一个:
干得好,一个:
使用位集类。。。
有了它,您可以始终在设置的标志和未设置的标志之间获得良好的控制关系
例子:
使用位集类。。。
有了它,您可以始终在设置的标志和未设置的标志之间获得良好的控制关系
例子:
也可以使用EnumMap执行此操作:
public class FlagMap {
private enum Flags {
FLAG1, FLAG2, FLAG3
}
private Map<Flags, Boolean> map = Collections.synchronizedMap(
new EnumMap<Flags, Boolean>(Flags.class));
public void setFlag(Flags flag, boolean value) {
map.put(flag, value);
}
public boolean getFlag(Flags flag) {
return map.get(flag);
}
public static void main(String args[]) {
FlagMap flagMap = new FlagMap();
// Set a flag:
flagMap.setFlag(Flags.FLAG1, true);
// Get a flag:
System.out.println("Flag 1: " + flagMap.getFlag(Flags.FLAG1));
}
}
公共类FlagMap{
私有枚举标志{
旗杆1,旗杆2,旗杆3
}
私有映射映射=Collections.synchronizedMap(
新的枚举映射(Flags.class));
公共无效设置标志(标志标志,布尔值){
map.put(标志、值);
}
公共布尔getFlag(Flags flag){
返回map.get(标志);
}
公共静态void main(字符串参数[]){
FlagMap FlagMap=新FlagMap();
//设置一个标志:
flagMap.setFlag(Flags.FLAG1,true);
//获取旗帜:
System.out.println(“Flag 1:+flagMap.getFlag(Flags.FLAG1));
}
}
您也可以使用EnumMap执行此操作:
public class FlagMap {
private enum Flags {
FLAG1, FLAG2, FLAG3
}
private Map<Flags, Boolean> map = Collections.synchronizedMap(
new EnumMap<Flags, Boolean>(Flags.class));
public void setFlag(Flags flag, boolean value) {
map.put(flag, value);
}
public boolean getFlag(Flags flag) {
return map.get(flag);
}
public static void main(String args[]) {
FlagMap flagMap = new FlagMap();
// Set a flag:
flagMap.setFlag(Flags.FLAG1, true);
// Get a flag:
System.out.println("Flag 1: " + flagMap.getFlag(Flags.FLAG1));
}
}
公共类FlagMap{
私有枚举标志{
旗杆1,旗杆2,旗杆3
}
私有映射映射=Collections.synchronizedMap(
新的枚举映射(Flags.class));
公共无效设置标志(标志标志,布尔值){
map.put(标志、值);
}
公共布尔getFlag(Flags flag){
返回map.get(标志);
}
公共静态void main(字符串参数[]){
FlagMap FlagMap=新FlagMap();
//设置一个标志:
flagMap.setFlag(Flags.FLAG1,true);
//获取旗帜:
System.out.println(“Flag 1:+flagMap.getFlag(Flags.FLAG1));
}
}
谢谢你的回答。我使用了混合方法。
我想说一个例子
private enum Flags{
Flag1,Flag2,Flag3,Flag4,Flag5,Flag6;
}
除此之外,我还使用了位集(flagSet
)
我不是在位集中设置硬编码索引值,而是从标志枚举中获取索引
flagSet.get(Flags.Flag1.ordinal()) //for getting
flagSet.set(Flags.Flag1.ordinal()) //For setting
谢谢你的回答。我使用了混合方法。 我想说一个例子
private enum Flags{
Flag1,Flag2,Flag3,Flag4,Flag5,Flag6;
}
除此之外,我还使用了位集(flagSet
)
我不是在位集中设置硬编码索引值,而是从标志枚举中获取索引
flagSet.get(Flags.Flag1.ordinal()) //for getting
flagSet.set(Flags.Flag1.ordinal()) //For setting
为什么不将标志号作为
int
参数传递(作为标志
数组的索引)?或者使用java.util.BitSet
您考虑过Map@ElliottFrisch…没有使用,因为我认为这会使它变得非常粗糙。如果是这种情况,我可以在同一个类中有一个布尔数组(而不是嵌套类),并可以直接操作它,例如标志[0]=true@wero从某个地方读到,对于少数几个标志,布尔数组的性能优于位集。为什么不将标志号作为int
参数传递(作为标志
数组的索引)?或使用java.util.BitSet
您是否考虑过Map@ElliottFrisch…没有使用,因为我认为这会使它变得非常粗糙。如果是这种情况,我可以在同一个类中有一个布尔数组(而不是嵌套类),并可以直接操作它,例如标志[0]=true@wero在某些地方读到布尔数组比位集提供更好的性能。这应该是注释而不是答案。是的,保存太快了。我将添加更多信息和示例。等等,我确实读过enumset,但不知道如何在这里使用。此外,使用ordinal()使其依赖于顺序,而顺序似乎不是t