成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么源碼中都使用16進(jìn)制進(jìn)行狀態(tài)管理?

開(kāi)發(fā) 前端
在計(jì)算機(jī)中,一個(gè)字節(jié)有八位,最大值為 1111 1111。對(duì)應(yīng)的10進(jìn)制數(shù)是255,對(duì)應(yīng)的16進(jìn)制是 FF。所以半個(gè)字節(jié)用16進(jìn)制是可以通過(guò)一個(gè)字母就能表示,而轉(zhuǎn)換成10進(jìn)制就是一個(gè)無(wú)規(guī)律的數(shù)字。

[[402867]]

前言

在Android源碼中,對(duì)于“多狀態(tài)”的管理總是通過(guò)16進(jìn)制數(shù)字來(lái)表示,類似這種格式:

  1. //ViewGroup.java 
  2.  
  3. protected int mGroupFlags; 
  4.  
  5. static final int FLAG_CLIP_CHILDREN = 0x1; 
  6. private static final int FLAG_CLIP_TO_PADDING = 0x2; 
  7. static final int FLAG_INVALIDATE_REQUIRED  = 0x4; 
  8. private static final int FLAG_RUN_ANIMATION = 0x8; 
  9. static final int FLAG_ANIMATION_DONE = 0x10; 
  10. private static final int FLAG_PADDING_NOT_NULL = 0x20; 

那么,你有沒(méi)有想過(guò)為什么遇到多狀態(tài)的管理,就選擇用16進(jìn)制?

簡(jiǎn)單的狀態(tài)表示

來(lái)舉個(gè)實(shí)際的例子,我們作為一個(gè)人,身上肯定會(huì)有很多標(biāo)簽,比如帥氣、可愛(ài)、博學(xué)、機(jī)智、懶惰、小氣。

針對(duì)這些標(biāo)簽,我們就可以設(shè)定不同的人設(shè):

  1. //定義實(shí)體類 
  2.  data class Person(var tag : String) 
  3.  
  4. //修改標(biāo)簽 
  5.  val person1 = Person("帥氣"
  6.  
  7.  //判斷標(biāo)簽 
  8.   fun isCute():Boolean{ 
  9.    return person1.tag == "可愛(ài)" 
  10.   } 

當(dāng)一個(gè)人只有一個(gè)標(biāo)簽的時(shí)候是很簡(jiǎn)單的,直接賦值或者取值判斷即可。但是,如果一個(gè)人有多個(gè)標(biāo)簽?zāi)?

也很簡(jiǎn)單,使用集合存儲(chǔ)即可:

  1. val person2 = Person(mutableListOf()) 
  2. person2.tags.add("帥氣"
  3. person2.tags.add("可愛(ài)"
  4.  
  5. person2.tags.remove("可愛(ài)"
  6.  
  7. person2.tags.contains("可愛(ài)")  

但是用到集合之后,這個(gè)計(jì)算就變得比較復(fù)雜了,由于remove和contains方法都是通過(guò)遍歷集合的方式實(shí)現(xiàn)的,從時(shí)間復(fù)雜度角度看的話,當(dāng)刪除某個(gè)標(biāo)簽或者判斷某個(gè)標(biāo)簽是否存在的時(shí)間復(fù)雜度都是O(n)。

有沒(méi)有什么辦法讓多個(gè)標(biāo)簽也像剛才的單個(gè)標(biāo)簽?zāi)敲春?jiǎn)單地使用操作呢?

二進(jìn)制運(yùn)算

當(dāng)然有啦,不然這篇文章也不會(huì)有了,在這之前,我們先復(fù)習(xí)下二進(jìn)制的幾種運(yùn)算。

  • 1、按位與(&)

當(dāng)兩個(gè)對(duì)應(yīng)位的值都為1,則結(jié)果為1,否則為0。

舉例:0x1 & 0x4

  1. 0001 & 
  2. 0100 
  3.      = 
  4. 0000 
  • 2、按位或(|)

當(dāng)兩個(gè)對(duì)應(yīng)位的值都只要有一位是1,則結(jié)果為1。

舉例:0x1 | 0x4

  1. 0001 | 
  2. 0100 
  3.      = 
  4. 0101 
  • 3、取反( ~ )

將一個(gè)數(shù)按位取反。

舉例:~ 0x1

  1. 0001 ~ 
  2.      = 
  3. 1110      

好了,有了這三種運(yùn)算,我們的狀態(tài)管理就足夠了。

引入16進(jìn)制

接下來(lái),就來(lái)完成一個(gè)完整的狀態(tài)管理例子。

  1. //設(shè)定所有狀態(tài)對(duì)應(yīng)的16進(jìn)制值 
  2.  
  3. //可愛(ài),對(duì)應(yīng)二進(jìn)制0001 
  4. val TAG_CUTE = Ox1   
  5. //帥氣,對(duì)應(yīng)二進(jìn)制0010  
  6. val TAG_HANDSOME = Ox2 
  7. //博學(xué),對(duì)應(yīng)二進(jìn)制0100 
  8. val TAG_LEARNED = Ox4 
  9.  
  10. var personTag = 0 

狀態(tài)增加

如果一個(gè)二進(jìn)制數(shù)字想留下另一個(gè)二進(jìn)制數(shù)字的痕跡,我們可以通過(guò)或運(yùn)算,這樣只要第二個(gè)數(shù)字某位上有1,那么最終的結(jié)果在同樣的位數(shù)肯定也是1。

所以,我們可以通過(guò)這個(gè)方法來(lái)完成狀態(tài)增加的功能:

  1. //增加可愛(ài)狀態(tài) 
  2. personTag |= TAG_CUTE 
  3.  
  4. 0000 | 
  5. 0001  
  6. 0001 

這樣操作之后,personTag的第四位上的數(shù)字就為1了,也就帶有TAG_CUTE這個(gè)標(biāo)記了。

狀態(tài)移除

按照上述的邏輯,狀態(tài)的移除其實(shí)就是需要把對(duì)應(yīng)的位數(shù)從1改為0。

假設(shè)personTag現(xiàn)在的值變成了二進(jìn)制數(shù)0111。

如果要?jiǎng)h除TAG_CUTE屬性,就需要把第四位的1改為0。那么我們可以做的操作就是先對(duì)TAG_CUTE取反,也就是把0001,變成了1110。然后再和personTag進(jìn)行與運(yùn)算,這樣第四位肯定就會(huì)變?yōu)?,而其他位上面的值不變。

  1. //personTag為二進(jìn)制數(shù)0111 
  2. personTag &= ~TAG_CUTE 
  3.  
  4. 0001 ~ 
  5. 1110 & 
  6. 0111 
  7. 0110 

完成對(duì)TAG_CUTE狀態(tài)的移除。

狀態(tài)判斷

同理,對(duì)是否有某個(gè)狀態(tài)的判斷,其實(shí)就是判斷在某個(gè)位上是否值為1。所以我們只需要對(duì)狀態(tài)進(jìn)行 與運(yùn)算,如果結(jié)果為0,就代表沒(méi)有這個(gè)狀態(tài),否則就代表有這個(gè)狀態(tài)。

  1. //personTag為二進(jìn)制數(shù)0111 
  2. (personTag & TAG_CUTE) != 0 
  3.  
  4. 0111 & 
  5. 0001 
  6. 0001 

結(jié)果不為0,所以代表personTag 包含了 TAG_CUTE 這個(gè)狀態(tài)。

注意的點(diǎn)

細(xì)心的朋友可能會(huì)發(fā)現(xiàn),剛才我們用到的16進(jìn)制值,跳過(guò)了Ox3這個(gè)值,這是為什么呢?

其實(shí)不難發(fā)現(xiàn),所謂的通過(guò)16進(jìn)制管理狀態(tài),其實(shí)是通過(guò)二進(jìn)制來(lái)管理狀態(tài),歸根結(jié)底是通過(guò)二進(jìn)制中的1所在的位數(shù)來(lái)進(jìn)行管理。

所以我們對(duì)狀態(tài)賦值,需要選取單獨(dú)占有一位的二進(jìn)制值,比如0001 ,0010,0100,1000,10000等等。

如果用了其他值會(huì)發(fā)生什么呢?舉個(gè)例子,增加Ox3的TAG。

  1. //懶惰,對(duì)應(yīng)二進(jìn)制0011 
  2. val TAG_LAZY = Ox3 
  3.  
  4.  
  5. //增加可愛(ài)狀態(tài) 
  6. personTag |= TAG_CUTE 
  7. //增加帥氣狀態(tài) 
  8. personTag |= TAG_HANDSOME 

在我們?cè)黾恿丝蓯?ài)和帥氣狀態(tài)之后,personTag的二進(jìn)制值為 0011。

這時(shí)候再對(duì)它進(jìn)行判斷,是否含有懶惰狀態(tài):

  1. //是否含有懶惰狀態(tài) 
  2. (personTag & TAG_LAZY) != 0 
  3.  
  4. 0011 & 
  5. 0011  
  6. 0011 

結(jié)果不為0,難道我們?cè)黾恿藨卸锠顟B(tài)嗎?很明顯沒(méi)有,我不懶但是卻說(shuō)我懶,這是誣陷!

所以你明白狀態(tài)取值的范圍了嗎?

為什么是16進(jìn)制?

到此,通過(guò)16進(jìn)制管理狀態(tài)的功能已經(jīng)實(shí)現(xiàn)了,很明顯這種方式管理狀態(tài)要簡(jiǎn)便許多,其根本原理就是通過(guò)二進(jìn)制的計(jì)算來(lái)完成對(duì)狀態(tài)的管理。

有人又要問(wèn)了,既然本質(zhì)是通過(guò)二進(jìn)制來(lái)完成管理,那么用10進(jìn)制來(lái)表示也可以啊,比如上述的例子:

  1. //設(shè)定所有狀態(tài)對(duì)應(yīng)的10進(jìn)制值 
  2.  
  3. //可愛(ài),對(duì)應(yīng)二進(jìn)制0001 
  4. val TAG_CUTE = 1   
  5. //帥氣,對(duì)應(yīng)二進(jìn)制0010  
  6. val TAG_HANDSOME = 2 
  7. //博學(xué),對(duì)應(yīng)二進(jìn)制0100 
  8. val TAG_LEARNED = 4 
  9.  
  10. var personTag = 0 

這跟16進(jìn)制不是一樣么?

從根本來(lái)說(shuō),確實(shí)是一樣的,但是16進(jìn)制有16進(jìn)制的好處,這就涉及到16進(jìn)制為什么被設(shè)計(jì)出來(lái)的原因了。

在計(jì)算機(jī)中,一個(gè)字節(jié)有八位,最大值為 1111 1111。對(duì)應(yīng)的10進(jìn)制數(shù)是255,對(duì)應(yīng)的16進(jìn)制是 FF。所以半個(gè)字節(jié)用16進(jìn)制是可以通過(guò)一個(gè)字母就能表示,而轉(zhuǎn)換成10進(jìn)制就是一個(gè)無(wú)規(guī)律的數(shù)字。為了方便,代碼中一般使用16進(jìn)制來(lái)表示 二進(jìn)制,就是因?yàn)槠淇梢院投M(jìn)制進(jìn)行一個(gè)更方便直觀的轉(zhuǎn)換。

總結(jié)

今天和大家介紹了下源碼中常用的通過(guò)16進(jìn)制轉(zhuǎn)換2進(jìn)制來(lái)管理狀態(tài)的方法。

 

簡(jiǎn)單的、基礎(chǔ)的道理解決大問(wèn)題,這也許就是大道從簡(jiǎn)的含義?

 

責(zé)任編輯:武曉燕 來(lái)源: 碼上積木
相關(guān)推薦

2024-10-24 19:25:48

2024-01-12 07:46:07

MQTT協(xié)議物聯(lián)網(wǎng)應(yīng)用.NET

2012-03-06 09:20:02

ibmdw

2022-09-08 08:02:26

MySQL隔離

2010-06-12 11:11:55

UML應(yīng)用

2011-04-01 16:23:14

Cacti監(jiān)控Nginx

2017-04-05 16:40:45

2021-02-11 13:30:56

Nodejs源碼c++

2021-04-26 20:44:59

Nacos方法String.inte

2012-09-26 10:02:44

框架開(kāi)發(fā)項(xiàng)目

2020-04-07 13:40:13

GraphQLAPI編程語(yǔ)言

2023-10-10 09:19:59

日志Java

2024-02-22 08:17:31

十六進(jìn)制數(shù)字計(jì)算

2014-08-13 14:48:01

LinuxShell腳本

2020-07-03 07:59:01

Linux服務(wù)systemd

2010-06-17 15:53:41

WAP協(xié)議

2017-07-03 13:33:42

AndroidItemDecorat

2014-11-21 10:50:26

JavaString

2011-03-08 12:59:38

proftpd

2015-06-19 10:38:54

數(shù)據(jù)中心配置管理系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日韩在线一区二区 | www.久久 | av一级毛片 | 国产精品免费观看 | 美女久久久久久久久 | 免费成人高清 | 在线午夜| 黄a在线播放 | 国产第一页在线观看 | 久久国| 美女福利网站 | 欧美精品在线播放 | 欧美日韩中文国产一区发布 | 99久久婷婷国产亚洲终合精品 | 欧美黑人狂野猛交老妇 | 蜜桃在线视频 | 久久国产精品视频观看 | 中文一区二区 | 国产一区二区精品在线 | 久久爱一区 | 伊人伊人伊人 | 中文字幕1区2区3区 日韩在线视频免费观看 | 成人国产精品免费观看 | 九九精品在线 | 亚洲日本一区二区三区四区 | 日韩三级 | 日本不卡一区二区三区 | 亚洲午夜精品 | 精品www| 国户精品久久久久久久久久久不卡 | 91久久| 不卡视频一区 | 亚洲精品国产偷自在线观看 | 天天干狠狠 | 免费看91| 91精品国产乱码久久久久久久 | 国产精品视频一区二区三区四蜜臂 | 久久精品福利视频 | 欧美日韩精品一区 | 婷婷精品 | 国产三级日本三级 |