2013-02-25 58 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;