2017-02-28 52 views
1

我使用的是通過或運算他們的價值觀像這樣將一個或多個枚舉庫包含一個枚舉set的元素:查找出來,如果一個int使用二進制運算

TestEnum { 
     VAL1(0x00000001), 
     VAL2(0x00000002), 
     VAL3(0x00000100), 
     VAL4(0x00000200), 
     VAL5(0x00000400), 
     VAL6(0x00000800), 
     VAL7(0x00001000), 
     VAL8(0x00002000), 
     VAL9(0x00004000), 
     VAL10(0x00008000), 

     // special values 
     VAL11(0x00000000), 
     VAL12(0x00000010), 
     VAL13(0x00000020), 
     VAL14(0x00000030); 

     private static final Map<Integer, TestEnum> TEST_ENUM_MAP; 

     // constructor, populate map etc. 

     public static TestEnum fromValue(final int value) { 
      return TEST_ENUM_MAP.get(value); 
     } 
    } 

    int valuesAsInt = 0; 

    for (TestEnum testEnum : TestEnum.values()) { 
     valuesAsInt |= testEnum.getValue(); 
    } 

我需要提取枚舉該合併產生valueAsInt牢記的是:

  • 的int必須包含特殊枚舉值之一(00000000 ... 0x00000030)
  • 的int可以包含零個或多個非特殊枚舉值。

這是我做過什麼:

private static final int MASK_FOR_SPECIAL_ENUMS = 0x000000FF; 

private static final ImmutableSet<TestEnum> SPECIAL_ENUMS = ImmutableSet.copyOf(Sets.newHashSet(TestEnum.VAL11, TestEnum.VAL12, TestEnum.VAL13, TestEnum.VAL14)); 

private void lookupTestEnums(final int valueAsInt) { 

     TestEnum testEnum = TestEnum.fromValue(valueAsInt & MASK_FOR_SPECIAL_ENUMS); 
    if (testEnum == null || !SPECIAL_ENUMS.contains(testEnum)) { 
     throw new ExceptionType(""); 
    } 
} 

只是取與用面膜是不夠的,因爲它會爲TestEnum值返回陽性結果,VAL1 (0x00000001)

有沒有更好的這樣做的方式?

+2

不知道你試着做什麼,而只是一個小小的建議:使用的,而不是一組枚舉的EnumSet。 http://docs.oracle.com/javase/7/docs/api/java/util/EnumSet.html –

回答

3

看來,你的MASK_FOR_SPECIAL_ENUMS必須等於0x000000F00x000000FF

然後,在檢查有效性之後,您的查找方法需要循環VAL1到VAL10值,並收集匹配的值。

換句話說,這樣的事情:

private static final int SPECIAL_MASK = 0x000000F0; 

int specialValue = valueAsInt & SPECIAL_MASK; 
int nonSpecialBits = valueAsInt & ~SPECIAL_MASK; 
for (TestEnum testEnum : TestEnum.values()) 
{ 
    int value = testEnum.getValue(); 
    if((value & SPECIAL_MASK) != 0) 
     continue; //this is one of the special values; ignore. 
    if((value & nonSpecialBits) == value) 
     collection.add(testEnum); 
} 
+0

我跑了一個快速測試,它最終在一個不同類型的問題。 0x00000001&0x000000F0是0x00000000,它對應於一個有效的枚舉VAL11。 – user1071840

+0

@ user1071840您需要取消掩碼。我用一個如何做到這一點的例子修改了我的答案。 –

0

你的問題沒有說明可以有只有一個特殊值;它指出有必須是一個,這是說至少一個的另一種方式,所以它是不可能做你想做的,因爲:

0x00000010 | 0x00000020 == 0x00000030 

一旦0x000000100x00000020已經在積累集體OR值,該值將與其中具有0x00000030的累計值無法區分。


然而,如果特殊值0x00000040,一個簡單的位掩碼會工作。

+2

問題說只能有一個特殊的枚舉值。 –

+0

@Mike不,它沒有。它表示*必須包含一個特殊的枚舉值*,並不排除不止一個。如果OP想要你聲稱的,OP應該使用你所做的魔語:「only」,即*必須包含** only **特殊枚舉值*之一,但OP沒有。 – Bohemian

+0

@波希米亞你是對的。我誤解了要求 – user1071840