2013-02-25 55 views
1

因此,我將應用程序中的一些位域轉換爲使用EnumSet,我很好奇是否有更好的方法來對X | Y進行比較。目前,我們這樣做:檢查是否使用EnumSet

if(bitfield & (X | Y) != 0) { 
    //do stuff 
} 

的EnumSet相當於似乎是:

if(enumSet.contains(X) || enumSet.contains(Y)) { 
    //do stuff 
} 

有一個更清潔的方式做到這一點?我知道你可以檢查containsAll()像這樣:

EnumSet flagsToCheck = EnumSet.of(X, Y); 
if(enumSet.containsAll(flagsToCheck)) { 
    //do stuff 
} 

但是,這對於要知道,如果(X & Y)設置的場景。有沒有相當的方法來檢查(X | Y)?我會認爲會有類似containsAny()的方法,但我沒有看到任何似乎有這種效果的東西。

回答

6

我會說現有的方法是更多比您的按位方式可讀。它確切地表達了你的意思:如果該集合包含X,或集合包含Y ......保持原樣。它已經乾淨了。

如果設置變得更大,你可以使用:

EnumSet<Foo> valid = EnumSet.of(Foo.X, Foo.Y, Foo.A, Foo.B); 
valid.retainAll(enumSet); 
if (valid.isEmpty()) { 
    ... 
} 

。我只是保持對於較大的情況下。對於兩個或三個選項,我會使用longhand形式。

+1

您可能想要相反('!valid.retainAll(enumSet)')來避免更改原始集合。 – assylias 2013-02-25 19:56:12

+0

我正要評論@ assylias的觀點。你可能是正確的,它作爲小集合的個體更具可讀性,看起來有點冗長。 – kcoppock 2013-02-25 19:57:21

+0

@assylias:完成,謝謝。 – 2013-02-25 20:08:44

1

您可以使用AbstractSet方法removeAll(如果找到任何元素,則爲true)。顯然,你可能想用原始集合的克隆來做到這一點。

+0

確實,這是檢查的好方法。我只是想避免不必要的複製。 – kcoppock 2013-02-25 19:55:47

+1

assylias做相反的評論(從您正在查找的值集中刪除所有原始集)也適用於此處。 – SJuan76 2013-02-25 22:31:43

1

如果您無法更新該設置,只需創建一個新的... @assylias是正確的。一個選項就是根據你想要的枚舉值創建一個新的集合,並相應地進行更改/驗證。

public enum ResultingState { 
    NOT_PERSISTED, PERSISTED, NOT_CALCULATED, CALCULATED; 
} 
EnumSet<ResultingState> errorsState = EnumSet.of(ResultingState.NOT_PERSISTED, ResultingState.NOT_CALCULATED); 
Collection<ResultingState> results = new HashSet<>(phaseResults.values()); 
boolean containsAny = results.retainAll(errorsState) && results.size() > 0;