Java 按位 & 运算符多重权限
Java Bitwise & operator multiple permission
我正在开发一个 java 网络应用程序,在一个数据库中 table 我有一个类型为 number 的列。但该列用于存储多个值。 (即如下所示的权限)
- 无=1;
- 查看次数 = 2;
- 加 = 4;
- 编辑=8;
- 插入 = 16;
- 删除 = 32;
- 全部=64;
问题
- 如果该列的值为 3 --> 那么我不需要选择任何内容,查看为
许可 .
- 如果该列的值为 12 --> 那么我需要选择添加,
编辑。
像这样
我知道我们可以通过按位运算符来做到这一点。任何实现此目的的代码都很棒。
首先,你的权限设置真的很奇怪; "nothing" 和 "all" 被分隔值是,呃。
好吧,您可以使用枚举并依赖序数;这有点hackish,但它可以工作。示例代码:
public enum Permission
{
NOTHING,
VIEW,
ADD,
EDIT,
INSERT,
DELETE,
ALL,
;
private static final Set<Permission> ALL_PERMISSIONS;
static {
final Set<Permission> set = values();
set.remove(NOTHING);
set.remove(ALL);
ALL_PERMISSIONS = Collections.unmodifiableSet(set);
}
private static final int NOTHING_ORDINAL = NOTHING.ordinal();
private static final int ALL_ORDINAL = ALL.ordinal();
public static Set<Permission> fromInt(final int value)
{
int mask;
mask = 1 << NOTHING_ORDINAL;
if (value & mask == mask)
return Collections.emptySet();
mask = 1 << ALL_ORDINAL;
if (value & mask == mask)
return ALL_PERMISSIONS;
final Set<Permission> set = EnumSet.noneOf(Permission.class);
for (final Permission p: ALL_PERMISSIONS) {
mask = 1 << p.ordinal();
if (value & mask == mask)
set.add(p);
}
return Collections.unmodifiableSet(set);
}
}
现在,为什么这样做:这是因为 Enum
值的 .ordinal()
是它在枚举中出现的索引。这里,NOTHING
的序数为 0,ALL
的序数为 6。因此,如果要将一个 int 映射到一组权限,则必须检查任何权限 p,p-设置整数中的第 bit。反过来,这意味着 i & (1 << p.ordinal()) == 1 << p.ordinal()
.
有关详细信息,请参阅 Enum
的 javadoc。
设计考虑:不要将 "nothing" 和 "all" 存储为可能的值。两者都可以映射为整数:
- 0 表示没有权限:
- 查看、添加等所有权限的所有值(基本上,因为这里您总共有 5 个权限,所以该值将是 (1 << 5) - 1)。
我认为你的意思是按位运算和二进制文字。
在您的情况下,您必须使用位掩码(固定版本,谢谢@Paul Boddington 和@Jaroslaw Pawlak):
final int MASK_NOTHING = 1;
final int MASK_VIEW = 0b10;
final int MASK_ADD = 0b100;
final int MASK_EDIT = 0b1000;
final int MASK_INSERT = 0b10000;
final int MASK_DELETE = 0b100000;
final int MASK_ALL = 0b1000000;
int column = 0; //YOUR DATA HERE
if((column & MASK_NOTHING) > 0)
{
}
if((column & MASK_VIEW) > 0)
{
}
请注意:所有可能的位标志都可以独立设置...因此要么避免一次设置多个位标志,要么处理所有这些情况
二进制文字:https://docs.oracle.com/javase/7/docs/technotes/guides/language/binary-literals.html Operators : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
感谢大家的回复。我使用 bitand 运算符创建了一个简单的实用程序,它非常适合上述用例
问题:
1 ) getPermission(3) 将 return 什么都没有并查看。
public static ArrayList<Integer> getPermission(int day) {
List<Integer> places = Arrays.asList(1, 2, 4, 8, 16, 32, 64);
ArrayList<Integer> d = new ArrayList<Integer>();
for (Integer i : places) {
if (bitWiseAnd(day, i)) {
d.add(i);
}
}
return d;
}
public static boolean bitWiseAnd(int bitwise, int operator) {
return (bitwise & operator) > 0;
}
我正在开发一个 java 网络应用程序,在一个数据库中 table 我有一个类型为 number 的列。但该列用于存储多个值。 (即如下所示的权限)
- 无=1;
- 查看次数 = 2;
- 加 = 4;
- 编辑=8;
- 插入 = 16;
- 删除 = 32;
- 全部=64;
问题
- 如果该列的值为 3 --> 那么我不需要选择任何内容,查看为 许可 .
- 如果该列的值为 12 --> 那么我需要选择添加, 编辑。
像这样
我知道我们可以通过按位运算符来做到这一点。任何实现此目的的代码都很棒。
首先,你的权限设置真的很奇怪; "nothing" 和 "all" 被分隔值是,呃。
好吧,您可以使用枚举并依赖序数;这有点hackish,但它可以工作。示例代码:
public enum Permission
{
NOTHING,
VIEW,
ADD,
EDIT,
INSERT,
DELETE,
ALL,
;
private static final Set<Permission> ALL_PERMISSIONS;
static {
final Set<Permission> set = values();
set.remove(NOTHING);
set.remove(ALL);
ALL_PERMISSIONS = Collections.unmodifiableSet(set);
}
private static final int NOTHING_ORDINAL = NOTHING.ordinal();
private static final int ALL_ORDINAL = ALL.ordinal();
public static Set<Permission> fromInt(final int value)
{
int mask;
mask = 1 << NOTHING_ORDINAL;
if (value & mask == mask)
return Collections.emptySet();
mask = 1 << ALL_ORDINAL;
if (value & mask == mask)
return ALL_PERMISSIONS;
final Set<Permission> set = EnumSet.noneOf(Permission.class);
for (final Permission p: ALL_PERMISSIONS) {
mask = 1 << p.ordinal();
if (value & mask == mask)
set.add(p);
}
return Collections.unmodifiableSet(set);
}
}
现在,为什么这样做:这是因为 Enum
值的 .ordinal()
是它在枚举中出现的索引。这里,NOTHING
的序数为 0,ALL
的序数为 6。因此,如果要将一个 int 映射到一组权限,则必须检查任何权限 p,p-设置整数中的第 bit。反过来,这意味着 i & (1 << p.ordinal()) == 1 << p.ordinal()
.
有关详细信息,请参阅 Enum
的 javadoc。
设计考虑:不要将 "nothing" 和 "all" 存储为可能的值。两者都可以映射为整数:
- 0 表示没有权限:
- 查看、添加等所有权限的所有值(基本上,因为这里您总共有 5 个权限,所以该值将是 (1 << 5) - 1)。
我认为你的意思是按位运算和二进制文字。
在您的情况下,您必须使用位掩码(固定版本,谢谢@Paul Boddington 和@Jaroslaw Pawlak):
final int MASK_NOTHING = 1;
final int MASK_VIEW = 0b10;
final int MASK_ADD = 0b100;
final int MASK_EDIT = 0b1000;
final int MASK_INSERT = 0b10000;
final int MASK_DELETE = 0b100000;
final int MASK_ALL = 0b1000000;
int column = 0; //YOUR DATA HERE
if((column & MASK_NOTHING) > 0)
{
}
if((column & MASK_VIEW) > 0)
{
}
请注意:所有可能的位标志都可以独立设置...因此要么避免一次设置多个位标志,要么处理所有这些情况
二进制文字:https://docs.oracle.com/javase/7/docs/technotes/guides/language/binary-literals.html Operators : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html
感谢大家的回复。我使用 bitand 运算符创建了一个简单的实用程序,它非常适合上述用例
问题:
1 ) getPermission(3) 将 return 什么都没有并查看。
public static ArrayList<Integer> getPermission(int day) {
List<Integer> places = Arrays.asList(1, 2, 4, 8, 16, 32, 64);
ArrayList<Integer> d = new ArrayList<Integer>();
for (Integer i : places) {
if (bitWiseAnd(day, i)) {
d.add(i);
}
}
return d;
}
public static boolean bitWiseAnd(int bitwise, int operator) {
return (bitwise & operator) > 0;
}