android位运算简单讲解
一、前言
在查看源碼中,經(jīng)常會(huì)看到很多這樣的符號(hào)“&”、“|”、“~”,咋一看挺高大上;仔細(xì)一看,有點(diǎn)懵;再看看,其實(shí)就是大學(xué)學(xué)過(guò)的再普通不過(guò)的與、或、非。今天小盆友就以簡(jiǎn)單的形式分享下,同時(shí)也是作為筆記記錄,等某天突然懵逼時(shí)可以回來(lái)看看,話不多說(shuō),開(kāi)始擼。
二、與或非是啥?
或許,大學(xué)上的課,在還沒(méi)畢業(yè)時(shí)就還給老師了,所以我們先重溫下。
1、與運(yùn)算符 &
知識(shí)點(diǎn):兩位同時(shí)為“1”,結(jié)果才為“1”,否則為“0”。
運(yùn)算規(guī)則: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)); 與運(yùn)算符運(yùn)行結(jié)果其實(shí)就是運(yùn)算的位要完全一樣,才保持原樣,否則就變?yōu)?。
2、或運(yùn)算符 |
知識(shí)點(diǎn):只要有一位為1,其值為1,否則位0。
運(yùn)算規(guī)則: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)); 或運(yùn)算符運(yùn)行結(jié)果其實(shí)就是只要有1,結(jié)果就為1。
3、非運(yùn)算符 ~
知識(shí)點(diǎn):如果位為0,結(jié)果是1。如果位為1,結(jié)果是0
運(yùn)算規(guī)則:~0=1; ~1=0;
System.out.println("~1 = " + ~(1)); System.out.println("~0 = " + ~(0)); 非運(yùn)算符運(yùn)行結(jié)果很驚喜!很意外!有沒(méi)有?!竟然不是0和1,這里不是計(jì)算機(jī)出問(wèn)題了,而是涉及到了計(jì)算機(jī)內(nèi)部的編碼的問(wèn)題,是不是想到了大學(xué)有一門課叫做《計(jì)算機(jī)科學(xué)導(dǎo)論》。詳細(xì)講解可以查看這里=>傳送門為了方便查看,我從文章截了一張圖
?
三、實(shí)戰(zhàn)
逼逼叨了這么多,其實(shí)位運(yùn)算符的文章很多,這里其實(shí)還少了一個(gè)異或運(yùn)算符,但因?yàn)闆](méi)有出現(xiàn)在實(shí)戰(zhàn)中,所以就不做多余的操作了。我們來(lái)進(jìn)行真正的運(yùn)用吧。
1、場(chǎng)景一(或運(yùn)算符的使用)
你有沒(méi)有在xml中這樣編寫(xiě)過(guò)布局
android:layout_gravity="bottom|right"我們這里就不用bottom、right在源碼中真實(shí)的值,以方便講解
這里的 bottom 和 right 在位上肯定是錯(cuò)開(kāi)的,這樣做位運(yùn)算時(shí),才能同時(shí)保存該控件 “居右”和“底部” 的屬性。
什么叫位上錯(cuò)開(kāi),且看下面代碼。
通過(guò)上面的代碼,或許你已經(jīng)恍然大悟(霧?),其實(shí)位錯(cuò)開(kāi)是為了或運(yùn)算時(shí),進(jìn)行值的保留。 讓兩個(gè)狀態(tài)的能夠保存在一個(gè)屬性中,或許你會(huì)問(wèn)這樣有什么好處了?我撓了下頭,想到了以下三個(gè)好處:
- 節(jié)省空間,避免不必要的屬性出現(xiàn)和維護(hù)成本(難道你想一個(gè)狀態(tài)用一個(gè)布爾值來(lái)維護(hù)么?手動(dòng)譏諷,哈哈)
- 獲取方便,編碼簡(jiǎn)潔
- 裝bi,不裝bi的程序員不是好的搬磚工
2、場(chǎng)景二(與運(yùn)算符的使用)
上一小節(jié)說(shuō)的是如何組裝成一個(gè)值,要怎么使用它呢?安卓源碼中怎么知道我們?cè)O(shè)置了 right 這個(gè)居右的狀態(tài)呢?這個(gè)便需要使用 “與” 運(yùn)算符來(lái) 取值。具體操作如下代碼:
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));?
運(yùn)算結(jié)果從上面的代碼很清晰的看出,用 “與” 運(yùn)算符進(jìn)行 “取值”。是不是有點(diǎn)小驚喜呢?
?
3、場(chǎng)景三(非運(yùn)算符的使用)
或許,你會(huì)有這樣的一個(gè)疑問(wèn),如果我想剔除當(dāng)前已經(jīng)包含的一個(gè)值,需要怎么辦?這時(shí)候就是“非”和“與”運(yùn)算符聯(lián)合使用的時(shí)候了,且看下面代碼
int right = 0x001; int bottom = 0x002; int top = 0x008; int state = right | bottom; System.out.println("剔除 right 狀態(tài)前 " + state); state &= ~right; System.out.println("剔除 right 狀態(tài)后 " + state); state &= ~top; System.out.println("剔除不存在的 top 狀態(tài) " + state); System.out.println(); 運(yùn)行結(jié)果是不是有點(diǎn)小激動(dòng)了呢?哈哈,在安卓源碼中運(yùn)用挺多,舉個(gè)栗子?,在ViewGroup中的requestDisallowInterceptTouchEvent方法便有用到,這里就不一一列舉。
敲黑板啦!!! 為什么上面能做到剔除呢?小盆友手寫(xiě)了下過(guò)程(多年沒(méi)寫(xiě)字,不要噴,哈哈哈哈)
?
四、小結(jié)
- 或運(yùn)算符整合值
- 與運(yùn)算符取值
- 與非剔除值
五、寫(xiě)在最后
或許還有很多更好玩的用法,但限于小盆友能力有限,文筆也一般般,所以就只能到這啦。如果您有更好或是更有趣的用法,或是本文有不妥之處,請(qǐng)與分享和糾正。編碼使我快樂(lè),哈哈哈。
鏈接:https://www.jianshu.com/p/5f41b3cc1909來(lái)源:簡(jiǎn)書(shū)
簡(jiǎn)書(shū)著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。
轉(zhuǎn)載于:https://www.cnblogs.com/wangzehuaw/p/9962398.html
總結(jié)
以上是生活随笔為你收集整理的android位运算简单讲解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一分钟经理的解释
- 下一篇: Codeforces Round #16