單個變量保存多個狀態(tài)

問題

在 Java 中,如何使用一個 byte 類型的變量保存多個 boolean 類型的值世吨?

場景

請選擇喜愛的球類運動(多選):

□ 足球 □ 籃球 □ 乒乓球
□ 臺球 □ 排球 □ 羽毛球

在如上所描述的場景中谎砾,如何使用一個 byte 類型的變量來保存各項是否選中?

回答

常規(guī)思路是定義 6 個 boolean 類型的變量埂奈,每個變量保存一項的狀態(tài), 選中為 true , 否則為 false戳吝。

boolean footballIsChecked = false;
...
boolean badmintonIsChecked = false;

在 Java 中,byte 類型的數(shù)據(jù)使用 8 位進行保存,每一位的值可能是 01兜看。理論上來講锥咸,byte 類型存儲空間的每一位可以表示一個 boolean 類型的值,1 表示 true细移,0 表示 false搏予。

byte sportCheckedState;
sportCheckedState = 0b0000_0000; //都沒選中
sportCheckedState = 0b0000_0001; //選中了足球
sportCheckedState = 0b0000_0010; //選中了籃球

因此,我們的需要解決問題變成了如何將 byte 類型某一位存儲空間的值設(shè)置為 01, 如何讀取某一位的值弧轧。

設(shè)置 byte 類型某一位的存儲空間的值

如何將某一位的值設(shè)置為 0 呢雪侥?

0 & 0 = 0
0 & 1 = 0

答:該位和 0 進行 & 運算。

如何將某一位的值設(shè)置為 1 呢精绎?

1 | 0 = 1
1 | 1 = 1

答:該位和 1 進行 | 運算速缨。

既然是設(shè)置某一位的值,就應(yīng)該不影響其他位的值代乃。

執(zhí)行 & 運算時旬牲,如何讓運算結(jié)果和運算數(shù)相等?

1 & 0 = 0
1 & 1 = 1

答:當(dāng)另外一個運算數(shù)為 1 時搁吓,運算結(jié)果和此運算數(shù)相同原茅。

執(zhí)行 | 運算時,如何讓運算結(jié)果和運算數(shù)相等堕仔?

0 | 0 = 0
0 | 1 = 1

答:當(dāng)另外一個運算數(shù)為 0 時擂橘,運算結(jié)果和此運算數(shù)相同。

綜上摩骨,設(shè)置某一位為 0 時通贞,進行 & 運算,輔助運算數(shù)(另外一個參與運算的數(shù))應(yīng)該符合這樣的規(guī)則:目標(biāo)位為0, 其他位為 1恼五。 例如設(shè)置最后一位昌罩,輔助運算數(shù)為 1111_1110

  1 0 1 0
& 1 1 1 0 //輔助運算數(shù)
 ----------
  1 0 1 0 //運算結(jié)果的前 3 位不變唤冈,最后一位設(shè)置為 0
  1 0 1 1
& 1 1 1 0 //輔助運算數(shù)
 ----------
  1 0 1 0 //運算結(jié)果的前 3 位不變峡迷,最后一位設(shè)置為 0

設(shè)置某一位為1 時,進行 | 運算你虹,輔助運算數(shù)應(yīng)該符合這樣的規(guī)則:目標(biāo)位為 1, 其它位為 0。例如設(shè)置最后一位彤避,輔助運算數(shù)為 0000_0001 傅物。

  1 0 1 0
| 0 0 0 1 //輔助運算數(shù)
 ----------
  1 0 1 1 //運算結(jié)果的前 3 位不變,最后一位設(shè)置為 1
  1 0 1 1
| 0 0 0 1 //輔助運算數(shù)
 ----------
  1 0 1 1 //運算結(jié)果的前 3 位不變琉预,最后一位設(shè)置為 1

讀取 byte 類型某一位的存儲空間的值

1 進行 & 時董饰,運算結(jié)果和另外一個運算數(shù)相同。

1 & 0 = 0
1 & 1 = 1

0 進行 & 時,運算結(jié)果為0 卒暂。

0 & 0 = 0
0 & 1 = 0

為了方便啄栓,我們希望 & 運算結(jié)果的其他位為 0,根據(jù) 0000_0000的運算結(jié)果可以推算出目標(biāo)位的值為 0也祠;根據(jù)目標(biāo)位為 1昙楚,其它位的值為 0 的運算結(jié)果可以推算出目標(biāo)位的值為 1

所以诈嘿,構(gòu)造出的輔助運算數(shù)應(yīng)該符合這樣的規(guī)則:目標(biāo)位的值為 1堪旧,其他位的值為 0。例如奖亚,倒數(shù)第二位應(yīng)該選取的輔助運算數(shù)為 0000_0010淳梦。

  1 0 1 0
& 0 0 1 0 //輔助運算數(shù)
 ----------
  0 0 1 0 //運算結(jié)果的 1、2昔字、4  位置為 0爆袍,第 3 為值為 1 ,即運算數(shù)第 3 位值為 1
  1 0 0 0
& 0 0 1 0 //輔助運算數(shù)
 ----------
  0 0 0 0 //運算結(jié)果的 1作郭、2螃宙、4  位置為 0,第 3 為值為 0 所坯,即運算數(shù)第 3 位值為 0

據(jù)此谆扎,我們可以得出結(jié)論:運算結(jié)果每一位的值都是 0 時,目標(biāo)位的值為 0芹助;運算結(jié)果存在值不為 0 的位時堂湖,目標(biāo)位的值為 1

示例

  // 每個狀態(tài)用一位表示状土,1 選中无蜂, 0 未選中
  private static final byte CHECKED_FOOTBALL = 0b0000_0001;

  private byte state = STATE_VALUE_DEFAULT;

  public void setFootballCheckedState(boolean isChecked) {
    if (isChecked) {
      state = (byte) (state | CHECKED_FOOTBALL);
    } else {
      state = (byte) (state & ~CHECKED_FOOTBALL);
    }
  }

  public boolean footballIsChecked() {
    return (state & CHECKED_FOOTBALL) == CHECKED_FOOTBALL;
  }

參考資料

happut : 單一字段存儲多狀態(tài)思路

代碼

XuMeng-0/android-study

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蒙谓,隨后出現(xiàn)的幾起案子斥季,更是在濱河造成了極大的恐慌,老刑警劉巖累驮,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酣倾,死亡現(xiàn)場離奇詭異,居然都是意外死亡谤专,警方通過查閱死者的電腦和手機躁锡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來置侍,“玉大人映之,你說我怎么就攤上這事拦焚。” “怎么了杠输?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵赎败,是天一觀的道長。 經(jīng)常有香客問我蠢甲,道長僵刮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任峡钓,我火速辦了婚禮妓笙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘能岩。我一直安慰自己寞宫,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布拉鹃。 她就那樣靜靜地躺著辈赋,像睡著了一般。 火紅的嫁衣襯著肌膚如雪膏燕。 梳的紋絲不亂的頭發(fā)上钥屈,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機與錄音坝辫,去河邊找鬼篷就。 笑死,一個胖子當(dāng)著我的面吹牛近忙,可吹牛的內(nèi)容都是我干的竭业。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼及舍,長吁一口氣:“原來是場噩夢啊……” “哼未辆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锯玛,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤咐柜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后攘残,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拙友,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年肯腕,在試婚紗的時候發(fā)現(xiàn)自己被綠了献宫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡实撒,死狀恐怖姊途,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情知态,我是刑警寧澤捷兰,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站负敏,受9級特大地震影響贡茅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜其做,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一顶考、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妖泄,春花似錦驹沿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至罚渐,卻和暖如春却汉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荷并。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工合砂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人源织。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓翩伪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雀鹃。 傳聞我的和親對象是個殘疾皇子幻工,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容