一、前言

在查看源码中,经常会看到很多这样的符号“&”、“|”、“~”,咋一看挺高大上;仔细一看,有点懵;再看看,其实就是大学学过的再普通不过的与、或、非。今天小盆友就以简单的形式分享下,同时也是作为笔记记录,等某天突然懵逼时可以回来看看,话不多说,开始撸。

二、与或非是啥?

或许,大学上的课,在还没毕业时就还给老师了,所以我们先重温下。

1、与运算符 &

知识点:两位同时为“1”,结果才为“1”,否则为“0”。

运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;

System.out.println("0 & 0" + (0 & 0));
System.out.println("0 & 1" + (0 & 1));
System.out.println("1 & 0" + (1 & 0));
System.out.println("1 & 1" + (1 & 1));
 
与运算符运行结果

其实就是运算的位要完全一样,才保持原样,否则就变为0。

2、或运算符 |

知识点:只要有一位为1,其值为1,否则位0。

运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1;

System.out.println("0 | 0 = " + (0 | 0));
System.out.println("0 | 1 = " + (0 | 1));
System.out.println("1 | 0 = " + (1 | 0));
System.out.println("1 | 1 = " + (1 | 1));
 
或运算符运行结果

其实就是只要有1,结果就为1。

3、非运算符 ~

知识点:如果位为0,结果是1。如果位为1,结果是0

运算规则:~0=1; ~1=0;

System.out.println("~1 = " + ~(1));
System.out.println("~0 = " + ~(0));
 
非运算符运行结果

很惊喜!很意外!有没有?!竟然不是0和1,这里不是计算机出问题了,而是涉及到了计算机内部的编码的问题,是不是想到了大学有一门课叫做《计算机科学导论》。详细讲解可以查看这里=>传送门为了方便查看,我从文章截了一张图

 
image

三、实战

逼逼叨了这么多,其实位运算符的文章很多,这里其实还少了一个异或运算符,但因为没有出现在实战中,所以就不做多余的操作了。我们来进行真正的运用吧。

1、场景一(或运算符的使用)

你有没有在xml中这样编写过布局

android:layout_gravity="bottom|right"

我们这里就不用bottom、right在源码中真实的值,以方便讲解

这里的 bottom 和 right 在位上肯定是错开的,这样做位运算时,才能同时保存该控件 “居右”和“底部” 的属性。
什么叫位上错开,且看下面代码。

// 0x001 = 0000 0001
int right = 0x001;
// 0x001 = 0000 0010
int bottom = 0x002;
// 结果 = 0000 0011 = 3
System.out.println("right | bottom = " + (right | bottom));
 
运算结果

通过上面的代码,或许你已经恍然大悟(雾?),其实位错开是为了或运算时,进行值的保留。 让两个状态的能够保存在一个属性中,或许你会问这样有什么好处了?我挠了下头,想到了以下三个好处:

  • 节省空间,避免不必要的属性出现和维护成本(难道你想一个状态用一个布尔值来维护么?手动讥讽,哈哈)
  • 获取方便,编码简洁
  • 装bi,不装bi的程序员不是好的搬砖工

2、场景二(与运算符的使用)

上一小节说的是如何组装成一个值,要怎么使用它呢?安卓源码中怎么知道我们设置了 right 这个居右的状态呢?这个便需要使用 “与” 运算符来 取值。具体操作如下代码:

int right = 0x001;
int bottom = 0x002;
int top = 0x008;
int state = right | bottom;
System.out.println("是否存在 right = " + ((state & right) == right));
System.out.println("是否存在 top = " + ((state & top) == top));
 
运算结果

从上面的代码很清晰的看出,用 “与” 运算符进行 “取值”。是不是有点小惊喜呢?

3、场景三(非运算符的使用)

或许,你会有这样的一个疑问,如果我想剔除当前已经包含的一个值,需要怎么办?这时候就是“非”和“与”运算符联合使用的时候了,且看下面代码

int right = 0x001;
int bottom = 0x002;
int top = 0x008;
int state = right | bottom;
System.out.println("剔除 right 状态前 " + state);
state &= ~right;
System.out.println("剔除 right 状态后 " + state);
state &= ~top;
System.out.println("剔除不存在的 top 状态 " + state);
System.out.println();
 
运行结果

是不是有点小激动了呢?哈哈,在安卓源码中运用挺多,举个栗子

android位运算简单讲解的更多相关文章

  1. Leetcode题目461:汉明距离(位运算-简单)

    题目描述: 两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目. 给出两个整数 x 和 y,计算它们之间的汉明距离. 注意:0 ≤ x, y < 231. 示例: 输入: x = ...

  2. C# 关于位运算的学习笔记

    一.理解什么是位运算 程序中的所有内容在计算机内存中都是以二进制的形式储存的(即:0或1),简单来说位运算就是直接对在内存中的二进制数的每位进行运算操作. 二.学习前先了解一下有哪些运算,运算符都怎么 ...

  3. Java二进制和位运算,这一万字准能喂饱你

    基础不牢,地动山摇.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习.关注公众号[BAT的乌托 ...

  4. C#位运算讲解与示例

    首先每一个权限数都是2的N次方数 如:k1=2 ; //添加 k2=4 ; //删除 k3=8; //修改 ... 如此定义功能权限数,当需要组合权限时,就需要对各个所拥有的权限数按位或了. 如: p ...

  5. 关于PHP位运算的简单权限设计

    写在最前面 最近想写一个简单的关于权限处理的东西,之前我也了解过用二进制数的位运算可以出色地完成这个任务.关于二进制数 的位运算,常见的就是“或.与.非”这三种简单运算了,当然,我也查看了下PHP手册 ...

  6. Android事件总线分发库EventBus3.0的简单讲解与实践

    Android事件总线分发库EventBus的简单讲解与实践 导语,EventBus大家应该不陌生,EventBus是一款针对Android优化的发布/订阅事件总线.主要功能是替代Intent,Han ...

  7. C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序

    C#中缓存的使用   缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可:  <%@ Outp ...

  8. Java中的位运算及简单的算法应用介绍

    众所周知,计算机底层是二进制.而java作为一门计算机编程语言,也对二进制的位运算提供了完整的支持. 在java中,int是32位的,也就是说可以用来实现32位的位运算.方便起见,我们一般用16进制对 ...

  9. C#位运算讲解与示例2

    在C#中可以对整型运算对象按位进行逻辑运算.按位进行逻辑运算的意义是:依次取被运算对象的每个位,进行逻辑运算,每个位的逻辑运算结果是结果值的每个位.C#支持的位逻辑运算符如表2.9所示. 运算符号 意 ...

随机推荐

  1. MATLAB 图像打开保存

    一.图片读取保存 (1)读取 clear all [filename,pathname]=uigetfile({'*.jpg';'*.bmp';'*.gif'},'选择图片'); if isequal ...

  2. 快速创建Flask Restful API项目

    前言 Python必学的两大web框架之一Flask,俗称微框架.它只需要一个文件,几行代码就可以完成一个简单的http请求服务. 但是我们需要用flask来提供中型甚至大型web restful a ...

  3. el-table分页展示数据

    <el-table :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)" :show- ...

  4. B 外地比赛

    时间限制 : - MS   空间限制 : - KB  评测说明 : 1s,256m 问题描述 何老板带着信竞队的k个同学出去外地打比赛.到达目的地后,何老板就找了一家酒店,准备住下.酒店工作人员告诉何 ...

  5. vue 跳转 同一路由不刷新问题解决

    vue跳转同一路径时,路由参数改变,但页面无法更新 问题原因 vue路由切换实际是组件间的切换,引用相同组件的时候,页面就无法更新 解决方案 方案1.watch监听路由参数变化,并重新渲染(谨慎选择) ...

  6. .NET项目升级手记:可为空引用

    c# 8引入了新特性:"可为空引用"(详情),这个功能个人觉得挺好的,能够非常明确的表现程序设计者的意图,编译器能够进行检查,尽最大可能减小NullReferenceExcepti ...

  7. 【数据库】MySQL数据库(四)

    一.对数据的操作(详细版) 1.添加数据 1> insert into 表名 (字段1,字段2...) values (值1,值2...); 2> insert into 表名 (字段1, ...

  8. docker-compose容器中redis权限问题

    遇到的问题:aof文件不断变大,导致服务器卡崩溃. 1.在服务器上拉取Bitnami/redis的镜像 2.出现aof权限不够问题,所以直接给aof文件加了权限,导致aof不断变大,最终服务器宕机. ...

  9. MAC中PHP7.3安装mysql扩展

    1.下载mysql扩展http://git.php.net/?p=pecl/database/mysql.git;a=summary 2.解压tar xzvf mysql-d7643af.tar.gz ...

  10. python3(二十七)property

    """ """ __author__ = 'shaozhiqi' # 绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单, # 但是, ...