卧槽,提取信息,Java還有這個騷操作

2022年10月23日09:59:12 科技 1123

在本文中,我們來看看如何使用位操作符實現低級別的位掩碼。我們將看到我們如何將一個單一的int變數作為一個單獨的數據容器。

卧槽,提取信息,Java還有這個騷操作 - 天天要聞

位掩碼

位掩碼允許我們在一個數字變數中存儲多個值。我們不再把這個變數看作一個整數,而是把它的每一個比特當作一個獨立的值。

因為一個比特可以等於 0 或 1,我們也可以把它看成是 false 或 true 。我們也可以把一組比特切開,把它們當作一個較小的數字變數甚至是一個String

舉個例子

假設我們有一個最小的內存空間,並且需要在一個int變數中存儲所有關於用戶賬戶的信息。前八位(來自32個可用位)將存儲boolean信息,如 "該賬戶是否激活?"或 "該賬戶是否溢價?"

至於剩下的24位,我們將把它們轉換成三個字元,作為用戶的標識符。

編碼

我們的用戶將有一個標識符 "AAA",他將有一個活躍的高級賬戶(存儲在前兩個比特)。在二進位表示中,它將看起來像。

String stringRepresentation = "01000001010000010100000100000011";

使用內置的Integer#parseUnsignedInt方法,可以很容易地將其編碼為一個int變數。

int intRepresentation = Integer.parseUnsignedInt(stringRepresentation, 2);
assertEquals(intRepresentation, 1094795523);

解碼

這個過程也可以用 Integer#toBinaryString 方法來反轉。

String binaryString = Integer.toBinaryString(intRepresentation);
String stringRepresentation = padWithZeros(binaryString);
assertEquals(stringRepresentation, "01000001010000010100000100000011");

提取一個比特

第一比特

如果我們想檢查我們賬戶變數的第一位,我們只需要使用順位 and 運算符和數字 1 作為掩碼。因為數字 1在二進位形式中只有第一位被設置為1,其餘的都是0,它將從我們的變數中刪除所有的位,只留下第一個完整的位。

10000010100000101000001000000011
00000000000000000000000000000001
-------------------------------- &
00000000000000000000000000000001

然後我們需要檢查產生的值是否不等於零。

intRepresentation & 1 != 0

任意位置的位

如果我們想檢查其他的位,我們需要創建一個適當的掩碼,這個掩碼需要在給定的位置上有一個位設置為1,其餘的設置為0。最簡單的方法是對我們已有的掩碼進行移位。

1 << (position - 1)

上面這行代碼的位置變數設置為3,將把我們的掩碼從 00000000000000000000000000000001 變成

00000000000000000000000000000100

因此,現在,比特方程將看起來像這樣。

10000010100000101000001000000011
00000000000000000000000000000100
-------------------------------- &
00000000000000000000000000000000

把所有這些放在一起,我們可以寫一個方法來提取給定位置上的單個比特。

private boolean extractValueAtPosition(int intRepresentation, int position) {
    return ((intRepresentation) & (1 << (position - 1))) != 0;
}

為了達到同樣的效果,我們也可以將intRepresentation變數向相反方向移動,而不是改變掩碼。

提取多個比特

我們可以用類似的方法從一個整數中提取多個比特。讓我們提取我們的用戶帳戶變數的最後三個位元組,並將其轉換為一個字元串。首先,我們需要通過將變數向右移動來擺脫前八位的影響。

int lastThreeBites = intRepresentation >> 8;
String stringRepresentation = getStringRepresentation(lastThreeBites);
assertEquals(stringRepresentation, "00000000010000010100000101000001");

我們仍然有32位,因為int總是有32位。然而,現在我們只對前24位感興趣,其餘的都是零,會很容易被忽略。我們創建的int變數可以很容易地用作整數ID,但是因為我們想有一個字元串ID,所以我們還有一個步驟要做。

我們將把二進位的字元串表示法分成8個字元的組,把它們解析成char變數,然後把它們連接成一個最終的String

為了方便起見,我們還將忽略空位元組。

Arrays.stream(stringRepresentation.split("(?<=\\G.{8})"))
  .filter(eightBits -> !eightBits.equals("00000000"))
  .map(eightBits -> (char)Integer.parseInt(eightBits, 2))
  .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
  .toString();

應用一個比特掩碼

我們也可以創建一個掩碼來同時檢查許多位,而不是提取和檢查單個位的值。我們想檢查我們的用戶是否有一個活躍的高級賬戶,所以他的變數的前兩個比特都設置為1。

我們可以用以前的方法分別檢查它們,但創建一個掩碼來選擇它們,會更快。

int user = Integer.parseUnsignedInt("00000000010000010100000101000001", 2);
int mask = Integer.parseUnsignedInt("00000000000000000000000000000011", 2);
int masked = user & mask;

因為我們的用戶有一個活躍的賬戶,但它不是高級賬戶,所以被屏蔽的值將只有第一個比特被設置為1。

assertEquals(getStringRepresentation(masked), "00000000000000000000000000000001");

現在,我們可以輕鬆而廉價地斷言一個用戶是否符合我們的條件。

assertFalse((user & mask) == mask);

總結

在本教程中,我們學習了如何使用位運算符來創建位掩碼,並應用它

科技分類資訊推薦

【新機】Pura 80 Pro+/Pro今日開售,標準版配置公布 - 天天要聞

【新機】Pura 80 Pro+/Pro今日開售,標準版配置公布

華為Pura 80系列於今早10:08迎來了首銷,大家都搶到了嗎?這次首銷機型為Pura 80 Pro+/Pro,Ultra首銷日期為本月26日,標準版將於7月開售,不過除了知道有這麼一個型號以及外觀,其他信息在發布會上並沒有披露,只是說會在7月開售。不過目前官方更新了Pura 80標準版的頁面,從規格信息我們也能看到標準版的大概配置信息。P...
【新機】LED燈帶沒有了?Nothing新機曝光 - 天天要聞

【新機】LED燈帶沒有了?Nothing新機曝光

近日海外博主曝光了疑似Nothing Phone(3)的高清渲染圖,能看到機子依然延續了透明後蓋的設計,不過標誌性的LED燈帶是去掉了。內部絲印蓋板具有豐富的科技感,居中奧利奧Deco,後置三攝,鏡頭的排列有點像一個猴子。那麼大家會給這個外觀設計打幾分呢?據悉Nothing Phone(3)將會是Nothing的首款真正旗艦手機,性能也會大...
內置風扇,不過處理器是...丨vivo大摺疊 C口有點怪 - 天天要聞

內置風扇,不過處理器是...丨vivo大摺疊 C口有點怪

此前主動式散熱風扇一直是紅魔遊戲手機的獨家賣點,對於機身散熱起到一定的幫助。不過接下來黑廠K系列新機也將用上這一技術。今天@數碼閑聊站曝光了黑廠新機K13 Turbo Pro的配置:新機將會採用6.8英寸1.5K OLED直面屏,解析度為2800*1280,支持144Hz刷新率,短焦指紋識別。前置1600萬像素,後置5000萬主攝+200萬湊數副攝。...
深度!剖析冬蟲夏草膠囊前10強,正宗品牌優勢在哪 - 天天要聞

深度!剖析冬蟲夏草膠囊前10強,正宗品牌優勢在哪

不少人開始關注冬蟲夏草膠囊,不僅因為它來自珍貴的天然資源,更因其逐步被現代人納入日常養護計劃。不過面對琳琅滿目的品牌,想找准真正靠譜的產品,確實有點難。本文將帶你深入分析冬蟲夏草膠囊行業前十強,看看哪些品牌更值得信賴。冬蟲夏草膠囊的優勢在哪
[評測] 乂度 XD05 Basic2:真正為電腦而生 - 天天要聞

[評測] 乂度 XD05 Basic2:真正為電腦而生

千呼萬喚始出來,猶抱琵琶半遮面。自去年開始,乂度開始全面翻新旗下最為經典的XD-05系列,有主打推力的Plus、主打台式的Basic、主打平衡的Bal,以及超級全能旗艦的PRO,(以及後面配置了6J1電子管的T),每一款都定位明確,構造了那
小米15Ultra再度跌至新低,2K屏+6000mAh+後置四攝,終於等到了 - 天天要聞

小米15Ultra再度跌至新低,2K屏+6000mAh+後置四攝,終於等到了

在手機行業曾經最「浮誇」的階段,後置攝像頭數量一度被當成噱頭來炒作。什麼五攝、六攝,甚至一度有人調侃,再這麼發展下去手機背面就要變成「蜂窩煤」。但現實很快給這波操作潑了冷水,用戶越來越明白,鏡頭數量不等於成像質量,盲目堆攝像頭只是「看上去很
榮耀618不講武德,512GB頂配版跌至1384元,5800mAh+一億像素 - 天天要聞

榮耀618不講武德,512GB頂配版跌至1384元,5800mAh+一億像素

用了這麼多年智能手機,很多人應該都有這樣的感受,一款手機想要長時間使用,不怕手機出現輕微的卡頓,就怕空間告急。一開始可能覺得128GB夠用,結果沒過多久,就被照片、視頻、應用、緩存塞得滿滿當當。刪個照片都得小心翼翼。