The use of Java bit operations in programming: bit masks (BitMask)

In Java, there are many bitwise operators, such as and (&), not (~), or (|), exclusive or (^), shift (<< and >>), etc. These operators are rarely used in everyday coding.

In one of the following examples, a bitmask (BitMask) is used, which contains a large number of bit operations. Not only in Java, but also in other programming languages.

For example, in a system, users generally have four kinds of permissions: Query (Select), Add (Insert), Modify (Update), and Delete (Delete). The four kinds of permissions can be combined in various ways, that is, there are 16 different Permission status (2 to the 4th power).

Permission

In general, you will think of using four boolean type variables to save:

public class Permission {
	
	// Whether to allow query
	private boolean allowSelect;
	
	// Whether to allow new additions
	private boolean allowInsert;
	
	// whether to allow deletion
	private boolean allowDelete;
	
	// whether to allow updates
	private boolean allowUpdate;

	// Omit Getter and Setter
}

The above uses four boolean type variables to save each permission state.

NewPermission

The following is another way. If you use a bit mask, you can use a binary number. Each bit represents a permission, 0 means no permission, and 1 means permission.

public class NewPermission {
	// Whether to allow query, the first bit of binary, 0 means no, 1 means yes
	public static final int ALLOW_SELECT = 1 << 0; // 0001
	
	// Whether to allow new addition, the second bit of binary, 0 means no, 1 means yes
	public static final int ALLOW_INSERT = 1 << 1; // 0010
	
	// Whether to allow modification, the third bit of binary, 0 means no, 1 means yes
	public static final int ALLOW_UPDATE = 1 << 2; // 0100
	
	// Whether to allow deletion, the fourth bit of binary, 0 means no, 1 means yes
	public static final int ALLOW_DELETE = 1 << 3; // 1000
	
	// store the current permission status
	private int flag;

	/**
	 * reset permissions
	 */
	public void setPermission(int permission) {
		flag = permission;
	}

	/**
	 * Add one or more permissions
	 */
	public void enable(int permission) {
		flag |= permission;
	}
	
	/**
	 * Remove one or more permissions
	 */
	public void disable(int permission) {
		flag &= ~permission;
	}
	
	/**
	 * Do you have certain permissions
	 */
	public boolean isAllow(int permission) {
		return (flag & permission) == permission;
	}
	
	/**
	 * whether some permissions are disabled
	 */
	public boolean isNotAllow(int permission) {
		return (flag & permission) == 0;
	}
	
	/**
	 * Does it only have certain permissions
	 */
	public boolean isOnlyAllow(int permission) {
		return flag == permission;
	}
}

In the above code, the permission items of each binary bit code are represented by four constants.

E.g:

ALLOW_SELECT = 1 << 0 converted to binary is 0001, the first bit of binary indicates Select permission.
ALLOW_INSERT = 1 << 1 converted to binary is 0010, the second bit of binary represents Insert permission.

The private int flag stores the activation and deactivation status of various permissions, which is equivalent to replacing the four boolean type variables in Permission.

The four binary bits of the flag are used to represent the status of the four permissions. The 0 and 1 of each bit represent the activation and deactivation of a permission. The permissions represented by some states are listed below:

flag delete Revise new Inquire  
1(0001) 0 0 0 1 Only queries are allowed (i.e. equal to ALLOW_SELECT)
2(0010) 0 0 1 0 Only new additions are allowed (ie equal to ALLOW_INSERT)
4(0100) 0 1 0 0 Modifications only (i.e. equal to ALLOW_UPDATE)
8(1000) 1 0 0 0 Only deletes are allowed (i.e. equal to ALLOW_DELETE)
3(0011) 0 0 1 1 Only query and add are allowed
0 0 0 0 0 Four permissions are not allowed
15(1111) 1 1 1 1 All four permissions are allowed

Using the bitmask method, you only need to use an integer greater than or equal to 0 and less than 16 to represent the status of all 16 permissions.

In addition, there are many methods for setting permissions and judging permissions, which require bit operations, such as:

public void enable(int permission) {
	flag |= permission; // equivalent to flag = flag | permission;
}

Call this method to add one or more permissions to the existing permissions.

Add an Update permission:

permission.enable(NewPermission.ALLOW_UPDATE);

Assuming that the existing permission is only Select, that is, the flag is 0001. Execute the above code, flag = 0001 | 0100, which is 0101, and have two permissions, Select and Update.

Add Insert, Update, Delete three permissions:

permission.enable(NewPermission.ALLOW_INSERT
    | NewPermission.ALLOW_UPDATE | NewPermission.ALLOW_DELETE);

The result of the NewPermission.ALLOW_INSERT | NewPermission.ALLOW_UPDATE | NewPermission.ALLOW_DELETE operation is 1110. Assuming that the existing permission is only Select, that is, the flag is 0001. flag = 0001 | 1110, which is 1111, has these four permissions, which is equivalent to adding three permissions.

If the above settings use the original Permission class, the following three lines of code are required:

permission.setAllowInsert(true);
permission.setAllowUpdate(true);
permission.setAllowDelete(true);

Comparison of the two

Set to allow only Select and Insert permissions

Permission

permission.setAllowSelect(true);
permission.setAllowInsert(true);
permission.setAllowUpdate(false);
permission.setAllowDelete(false);

NewPermission

permission.setPermission(NewPermission.ALLOW_SELECT | NewPermission.ALLOW_INSERT);

Determine whether to allow Select and Insert, Update permissions

Permission

if (permission.isAllowSelect() && permission.isAllowInsert() && permission.isAllowUpdate())

NewPermission

if (permission. isAllow (NewPermission.ALLOW_SELECT
    | NewPermission.ALLOW_INSERT | NewPermission.ALLOW_UPDATE))

Determine whether only Select and Insert permissions are allowed

Permission

if (permission.isAllowSelect() && permission.isAllowInsert()
    && !permission.isAllowUpdate() && !permission.isAllowDelete())

NewPermission

if (permission. isOnlyAllow (NewPermission.ALLOW_SELECT | NewPermission.ALLOW_INSERT))

Comparing the two, you can feel the advantages of the MyPermission bit mask method compared to Permission, which can save a lot of code. Bit operations are the underlying operations, which are very efficient and easy to understand.

some source code using bitmasks

java.lang.reflect.Edit

In Java reflection, java.lang.reflect.Modifier is used to determine the modifiers contained in classes, member variables, methods, etc. In Modifier's source code you can see:

public static final int PUBLIC           = 0x00000001;
public static final int PRIVATE          = 0x00000002;  
public static final int PROTECTED        = 0x00000004;  
public static final int STATIC           = 0x00000008;  
public static final int FINAL            = 0x00000010;  
public static final int SYNCHRONIZED     = 0x00000020;
// ......
public static boolean isProtected(int mod) {
	return (mod & PROTECTED) != 0;
}
public static boolean isStatic(int mod) {
	return (mod & STATIC) != 0;
}

原文链接:http://xxgblog.com/2013/09/15/java-bitmask/

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324844597&siteId=291194637