专栏首页呼延用int来表示多个bool判断

用int来表示多个bool判断

背景介绍

位操作,想必大家在学习计算机基础知识的时候都有所接触过,但是日常却老是想不起来使用,今天就提供一个使用的思路.

我们经常需要表示多个bool变量,比如:当一个人秃头并且背着双肩包,穿着格子衬衫,我们就叫他程序员,羞辱一下他.

那么正常的情况下,我们需要些三个if/else来实现这个操作:

    if(tutou){
        if(hasAshuangjianbao){
            if(inTShirt){
                System.out.println("this is a programer");
            }
        }
    }

当条件逐渐增多,这样的代码会越来越难看.因此我们考虑一下使用bit.

int表示bool

一个int在java中是4个字节,也就是工32bits.每一个bit有0,1两种状态,那么就可以表示true/false两种状态.

那么我们设计一下:

  1. 第一位表示是否是秃头,为1的时候为真.换算成int就是0代表不秃头,1代表秃头.
  2. 第二位表示是否背着双肩包.为10,11的时候表示有,01,00表示没有.
  3. 第三位表示是否穿子格子衬衫,1表示有,对应的序列为110,111,101,100四种,0表示没有010,011,001,000表示没有.

发现规律了吧,当我们要表示三个布尔值时,总共有8中可能的序列,正好对应了三种状态的排列组合,2 * 2 * 2 = 8.

我们想表示一个人,没有秃头,穿着格子衬衫,背着双肩包使用的序列是110,对应int中的6.

或 |

通过或我们可以拿到多个状态的并集.比如 1,2,4进行或操作之后,拿到的是111也就是7,所以7可以代表三个状态全部为真.

与 &

通过 & 操作可以拿到给定结果(

操作拿到的)和给定状态(你选一个咯)的并集.比如上面拿到的7,你想验证是否满足秃头(1),那么执行7 & 1拿到的结果如果为1即满足.

result & tag = = tag.

原理清楚了我们看一下代码实现.

import mian.AbstractMain;

/**
 * Created by pfliu on 2019/05/09.
 */
public class BitIntTest extends AbstractMain {


    public static void main(String[] args) {
        new BitIntTest().parseArgsAndRun(args);
    }

    @Override
    public void run() {
        int flag = 0;

        flag |= 1;
        System.out.println(Flag.isSet(flag, Flag.TU_TOU));
        System.out.println(Flag.isSet(flag, Flag.INAPACKAGE));

        flag |= 2;
        System.out.println(Flag.isSet(flag, Flag.INAPACKAGE));
        System.out.println(Flag.isSet(flag, Flag.TU_TOU));

        System.out.println(Flag.isAllSet(flag,Flag.TU_TOU,Flag.INAPACKAGE));

        flag |= 3;
        System.out.println(Flag.isAllSet(flag, Flag.INAPACKAGE, Flag.TU_TOU, Flag.INTSHIRT));

    }


    public static final class Flag {
        static int TU_TOU = 1;
        static int INAPACKAGE = 2;
        static int INTSHIRT = 4;


        public static boolean isSet(int flag, int tag) {
            return (flag & tag) == tag;
        }

        public static boolean isAllSet(int flag, int... tags) {
            int tag = 0;
            for (int i : tags) {
                tag |= i;
            }
            return (flag & tag) == tag;
        }
    }
}

比较核心的就是Flag内部类,我们在其中实现了两个方法.

  1. isSet: 验证是否满足给定的tag.比如6 & 1,那就是不满足.5 & 1就是满足.

isAllSet. 验证是否满足给定的所有条件,这里用了一个可变参数的方法.首先对所有给定的tag相

,然后重复1中的操作.

JDK中的实现

java.lang.reflect包中,有一个Modifier类.使用的就是这个思想.

这个类位于反射包中,主要是用于,在反射过程中,拿到的方法,变量等等,然后通过这个类来识别他们的修饰符,public/static/native等等.

因为这些修饰符可能是冲突的,可能是可以并存的,因此使用这种实现方法.

下面是类中对于修饰符的常量定义.(使用16进制是为了好看.看起来更加的直观).

    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 final int VOLATILE         = 0x00000040;

    public static final int TRANSIENT        = 0x00000080;

    public static final int NATIVE           = 0x00000100;

    public static final int INTERFACE        = 0x00000200;

    public static final int ABSTRACT         = 0x00000400;

    public static final int STRICT           = 0x00000800;

写一段代码测试一下:

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * Created by pfliu on 2019/05/10.
 */
public class ModifiersTest {

    private static int age = 999;

    public static void main(String[] args) throws NoSuchFieldException {
        Field myAge = ModifiersTest.class.getDeclaredField("age");
        int ageMod = myAge.getModifiers();


        System.out.println("打印十进制:" + ageMod);
        System.out.println("是否是private:" + Modifier.isPrivate(age));
        System.out.println("是否是final:" + Modifier.isFinal(age));

    }
}

打印结果为:

打印十进制:10
是否是private:true
是否是final:false

原理和上面自己实现的类似,这里不再赘述.有兴趣的胖友可以查看JDK源码学习一下,这个类比较简单.

ChangeLog

2019-05-09 完成

以上皆为个人所思所得,如有错误欢迎评论区指正。

欢迎转载,烦请署名并保留原文链接。

联系邮箱:huyanshi2580@gmail.com

更多学习笔记见个人博客——>呼延十

var gitment = new Gitment({ id: '用int来表示多个bool判断', // 可选。默认为 location.href owner: 'hublanker', repo: 'blog', oauth: { client_id: '2297651c181f632a31db', client_secret: 'a62f60d8da404586acc965a2ba6a6da9f053703b', }, }) gitment.render('container')



本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 面试常用排序算法总结

    其他的排序算法也经常会问到,虽然在工作中,我们很少有需要自己手写排序算法的机会,但是这种入门级的算法却是证明我们能力的一种简单方法.因此要熟悉掌握.

    呼延十
  • [随缘一题]雷达监测

    一个2D平面上有一堆雷达(雷达有x, y坐标,以及能探测到的范围r半径)。现在有一辆小车要从y = 0和y = 1的区间里面通过并且不能被雷达探测到。若被检测到...

    呼延十
  • 多级 Hashmap的优化

    Java程序员想必对Map<String,Map<String,Object>>类型的数据结构很熟悉, 并且深恶痛绝,在以前介绍过一种通用的处理方法, 我们可以...

    呼延十
  • 线程池工作窃取实例

    ForkJoinPool主要用到的是双端队列,不过这里我们粗糙的实现的话,也可以不用到deque。

    codecraft
  • 【递归打卡2】求两个有序数组的第K小数

    给定两个有序数组arr1和arr2,已知两个数组的长度分别为 m1 和 m2,求两个数组中的第 K 小数。要求时间复杂度O(log(m1 + m2))。

    帅地
  • LintCode 600. 包裹黑色像素点的最小矩形(BFS)

    一个由二进制矩阵表示的图,0 表示白色像素点,1 表示黑色像素点。 黑色像素点是联通的,即只有一块黑色区域。 像素是水平和竖直连接的,给一个黑色像素点的坐标...

    Michael阿明
  • 【Java面试复习经典】传智播客Java就业班入学测试题及答案解析(2012年版)

      共50道题,每道题2分,总分100分,80分为合格。   注意,题目有多选,也有单选。请认真作答。

    黑泽君
  • 历届试题 核桃的数量

    小张是软件项目经理,他带领3个开发组。工期紧,今天都在加班呢。为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑)。他的要求是:

    刘开心_1266679
  • JDK1.9-常用类Arrays

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    cwl_java
  • 高阶函数和Java的Lambda

    java 8引入了函数式编程。函数式编程重点在函数,函数变成了Java世界里的一等公民,函数和其他值一样,可以到处被定义,可以作为参数传入另一个函数,也可以作为...

    fengzhizi715

扫码关注云+社区

领取腾讯云代金券