Java 按位或、按位与、按位取反的妙用

文章摘要:
1、按位或:给指定位设定为1;
2、按位与:清零、取特定位;


一、按位或的作用
用途:给指定位设定为1;
其中LAST_BIT_FLAG 就是我们经常用到的标记位。

1、为number最后1位赋值为1.

int LAST_BIT_FLAG = 0x01;
int number = 0x60; //0x 0110 0000;
int result = number | LAST_BIT_FLAG; //0x 0110 0001;
System.out.println("number is:"+number
        +",result is:"+result);
//number is:96,result is:97

二、按位与的作用
用途:清零、取特定位

1、为number最后1位,清零。

int ZERO_FLAG = 0xfe;//ZERO_FLAG = ~LAST_BIT_FLAG ;
int number = 0x6f; //0x 0110 1111;
int result = number & ZERO_FLAG; //0x 0110 0000;
System.out.println("number is:"+number
 +",result is:"+result);
//number is:111,result is:110

总结:清零FLAG = 赋值FLAG取反。

2、分别取出number的高四位,与低四位

int LOWER_FOUR_BIT_FLAG = 0x0f,HIGH_FOUR_BIT_FLAG = 0xf0;
int number = 0x6f;                         //0x 0110 1111;
int lowResult = number & LOWER_FOUR_BIT_FLAG; //0x 0000 1111;
int highResult = number & HIGH_FOUR_BIT_FLAG; //0x 0110 0000;
System.out.println("number is:"+number
 +",lower4bit is:"+lowResult
 +",high4bit is:"+highResult);
//number is:111,lower4bit is:15,high4bit is:96

三、应用案例

场景:
短信简单分为三部分,主题、附件、正文。用户编辑短信,主题、正文等会发生改变,现在:需要打印短信状态,以及用户每次操作,改变了短信的那部分。

分析:

  • 1、短信状态可以使用标识位(flags)来表示。
    设定状态使用“或”操作:flags |=HAS_SUBJECT;
    取消状态使用“与”、“非”操作:flags &=~HAS_SUBJECT;
  • 2、按位异或:相同为0,不同为1。
    每次短信操作改变部分:新flags与旧的flags 按位异或。
private static final int HAS_SUBJECT = (1 << 0); // 1{0000 0001}
private static final int HAS_ATTACHMENT = (1 << 1); // 2{0000 0010}
private static final int HAS_CONTENT = (1 << 2); // 4{0000 0100}

    static class Sms {
        // 短信,初始化flag = 0,不含有主题、附件、正文
        private int flags = 0;

        private void updateSmsState(int state, boolean has) {
            int oldFlags = flags;
            if (has) {
                flags |= state;
            } else {
                flags &= ~state;
            }
            // 按位 异或,得到变化的flags
            int flagsChanges = oldFlags ^ flags;
            if ((flagsChanges & HAS_SUBJECT) != 0) {
                System.out.println("\t【主题】标记状态发生了改变!");
            } else if ((flagsChanges & HAS_ATTACHMENT) != 0) {
                System.out.println("\t【附件】标记状态发生了改变!");
            } else if ((flagsChanges & HAS_CONTENT) != 0) {
                System.out.println("\t【正文】标记状态发生了改变!");
            } else {
                System.out.println("\tflags标记状态没有发生改变!");
            }
        }

        private boolean hasSmsSubject(int smsFlag) {
            return (smsFlag & HAS_SUBJECT) > 0;
        }

        private boolean hasSmsAttachment(int smsFlag) {
            return (smsFlag & HAS_ATTACHMENT) > 0;
        }

        private boolean hasSmsContent(int smsFlag) {
            return (smsFlag & HAS_CONTENT) > 0;
        }

        public String toString() {
            String hasSubject = hasSmsSubject(flags) ? "[主题]" : "";
            String hasAttachment = hasSmsAttachment(flags) ? "[附件]" : "";
            String hasContent = hasSmsContent(flags) ? "[正文]" : "";
            return "短信:" + hasSubject
                    + "," + hasAttachment
                    + "," + hasContent;
        }
    }

测试:

        // 初始化短信对象
        Sms sms = new Sms();
        System.out.println("初始化短信:" + sms);

        // 给短信设定主题
        sms.updateSmsState(HAS_SUBJECT, true);
        System.out.println("短信添加主题后:" + sms);

        // 给短信设定附件
        sms.updateSmsState(HAS_ATTACHMENT, true);
        System.out.println("短信添加附件后:" + sms);

        // 给短信设定正文
        sms.updateSmsState(HAS_CONTENT, true);
        System.out.println("短信添加正文后:" + sms);

        // 短信不能含有附件
        sms.updateSmsState(HAS_ATTACHMENT, false);
        System.out.println("短信去除附件后:" + sms);

你可能感兴趣的:(Java 按位或、按位与、按位取反的妙用)