2010-01-01 29 views
17

que quiero hacer algo como esto:crear una máscara de bit de permiso en Java

public enum Permissions 
{ 
    CanBlah1, 
    CanBlah2, 
    CanBlah3 
} 

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

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

se puede hacer esto en Java así? (Estoy procedentes de aC# fondo)

Respuesta

37

Puede hacerlo fácilmente usando 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

Y, por supuesto, EnumSet se implementa como una máscara de bits bajo el capó. – Ross

+0

Ellos son. Utiliza 'long' para hasta 64 matrices de bytes 'Enumerados', llamado' JubmoSet'. –

0

Por lo que yo sé operador de bits no está definido para este tipo de enumeración

+0

Sí, pero 'EnumSet' tiene las operaciones de conjunto esenciales, por ejemplo unión a través de 'addAll()' e intersección a través de 'retainAll()'. Ver también: http://en.wikipedia.org/wiki/Set_(mathematics) – trashgod

3

Mientras que no recomendaría puede solicitar el ordinal() de una enumeración y usarlo para operaciones de bits. Por supuesto, ya que no se puede definir lo que el ordinal es de una enumeración, hay que insertar valores falsos para obtener los ordinales derecho

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

Aviso una enumeración Bogus necesaria para introducirse de manera que

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

puntos por mostrar ordinal, ¡no lo sabía! – Thufir

7

Esta es otra opción, que es similar a la solución ordinal, excepto que puede usar el | y & operadores con este:

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

o:

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 usted se pegó en la pre Java 7 Era (Android), puede intentar el siguiente código:

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

}

Cuestiones relacionadas