2010-01-01 8 views
17

ich so etwas wie dies tun wollen:eine Genehmigung Bitmaske in Java erstellen

public enum Permissions 
{ 
    CanBlah1, 
    CanBlah2, 
    CanBlah3 
} 

byte[] userPerm = Permissions.CanBlah1 | Permissions.CanBlah2; 

// check permssions 
// 
if(userPerm && Permissions.CanBlah1 == Permissions.CanBlah1) 
{ 
     // do something 
} 

Können Sie dies wie in Java zu tun? (Ich komme aus aC# Hintergrund)

Antwort

37

Sie können es leicht EnumSet

import java.util.EnumSet; 

import static java.util.EnumSet.of; 
import static java.util.EnumSet.range; 
import static so.User.Permissions.CanBlah1; 
import static so.User.Permissions.CanBlah2; 
import static so.User.Permissions.CanBlah3; 

public class User { 
    public enum Permissions { 
     CanBlah1, 
     CanBlah2, 
     CanBlah3 
    } 

    public static void main(String[] args) throws Exception { 
     EnumSet<Permissions> userPerms = of(CanBlah1, CanBlah2); 
     System.out.println(userPerms.contains(CanBlah1)); //true 
     System.out.println(userPerms.contains(CanBlah2)); //true 
     System.out.println(userPerms.contains(CanBlah3)); //false 
     System.out.println(userPerms.containsAll(of(CanBlah1, CanBlah3))); //false 
     System.out.println(userPerms.containsAll(range(CanBlah1, CanBlah2))); //true 
     System.out.println(userPerms.containsAll(range(CanBlah1, CanBlah3))); //false 
    } 

} 
+7

Und natürlich ist EnumSet als Bitmaske unter der Haube implementiert. – Ross

+0

Sie sind. Es verwendet "long" für bis zu 64 Enums-Byte-Arrays, sogenannte 'JubmoSet'. –

0

Soweit ich bitweise Operator weiß, ist nicht definiert für Aufzählungstypen

+0

Ja, aber "EnumSet" hat die wesentlichen Einstellungen, z union über 'addAll()' und Schnittpunkt über 'retainAll()'. Siehe auch: http://en.wikipedia.org/wiki/Set_(mathematics) – trashgod

3

Sie verwenden Während würde ich nicht empfehlen Sie können nach der Ordnungszahl (ordinal()) einer Aufzählung fragen und diese für Bitoperationen verwenden. Natürlich, da Sie nicht definieren können, was die Ordnungs für eine Enumeration ist, müssen Sie die ordinals rechts

enum Example { 
    Bogus,   --> 0 
    This,    --> 1 
    That,    --> 2 
    ThisOrThat  --> 3 
}; 

Hinweis ein Bogus Enum erhalten falsche Werte einfügen, um benötigt eingeführt werden, so dass

ThisOrThat.ordinal() == This.ordinal() | That.ordinal() 
+0

Punkte für die Ordnungszahl, wusste nicht darüber! – Thufir

7

Dies ist eine andere Option, die der ordinalen Lösung ähnelt, außer dass Sie die | verwenden können und & Betreiber mit diesem:

public enum Permissions { 
    CanBlah1(1), 
    CanBlah2(2), 
    CanBlah3(4); 

    public int value; 

    Permissions(int value) { 
     this.value = value; 
    } 
    public int value() { 
     return value; 
    } 
} 

public static void main(String[] args) { 
    int userPerm = Permissions.CanBlah1.value() | Permissions.CanBlah2.value(); 
    // check permssions 
    // 
    if((userPerm & Permissions.CanBlah1.value()) == Permissions.CanBlah1.value()) 
    { 
     // do something 
    } 
} 

oder:

public enum Permissions { 
     CanBlah1, 
     CanBlah2, 
     CanBlah3; 

     public int value() { 
      return 1<<ordinal(); 
     } 
    } 

    public static void main(String[] args) { 
     int userPerm = Permissions.CanBlah1.value() | Permissions.CanBlah2.value(); 
     // check permssions 
     // 
     if((userPerm & Permissions.CanBlah1.value()) == Permissions.CanBlah1.value()) 
     { 
      // do something 
     } 
    } 
2

Wenn Sie in der Pre Java 7 Era (Android) stecken können Sie den folgenden Code versuchen:

public enum STUFF_TO_BIT_BASK { 
THIS,THAT,OTHER; 

public static int getBitMask(STUFF_TO_BIT_BASK... masks) { 
    int res = 0; 

    for (STUFF_TO_BIT_BASK cap : masks) { 
     res |= (int) Math.pow(2, cap.ordinal()); 
    } 

    return res; 
} 

public boolean is(int maskToCheck){ 
    return maskToCheck | (int) Math.pow(2, this.ordinal()); 
} 

}