2010-01-01 5 views
17

Je veux faire quelque chose comme ceci:créer un masque de bits d'autorisation en java

public enum Permissions 
{ 
    CanBlah1, 
    CanBlah2, 
    CanBlah3 
} 

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

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

Pouvez-vous faire en Java comme ça? (Je viens de fond aC#)

Répondre

37

Vous pouvez facilement le faire en utilisant 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

Et, bien sûr, EnumSet est implémenté comme un masque de bits sous le capot. – Ross

+0

Ils sont. Il utilise 'long' pour jusqu'à 64 tableaux d'octets' Enums', appelés 'JubmoSet'. –

0

Pour autant que je sais que l'opérateur au niveau du bit est définie pour les types enum

+0

Oui, mais 'EnumSet' a les opérations de réglage essentielles, par exemple union via 'addAll()' et l'intersection via 'retainAll()'. Voir aussi: http://en.wikipedia.org/wiki/Set_(mathematics) – trashgod

3

Bien que je ne recommanderais pas vous pouvez demander l'ordinal() d'une énumération et l'utiliser pour les opérations sur les bits. Bien sûr, puisque vous ne pouvez pas définir le nombre ordinal pour un ENUM, vous devez insérer des valeurs fausses pour obtenir les ordinaux droit

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

Avis d'un ENUM Bogus devait être introduit afin que

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

points pour montrer ordinale, ne savait pas à ce sujet! – Thufir

7

Ceci est une autre option, qui est similaire à la solution ordinale, sauf que vous pouvez utiliser le | et & opérateurs avec ceci:

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 
    } 
} 

ou:

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

Si vous coincé dans l'ère pré Java 7 (Android), vous pouvez essayer le code suivant:

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()); 
} 

}

Questions connexes