91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java位域的示例分析

發布時間:2021-07-24 09:36:49 來源:億速云 閱讀:139 作者:小新 欄目:編程語言

這篇文章主要介紹Java位域的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

這個概念是在 Effective Java中了解到的, 可以通過EnumSet來代替位域這種方式表達.并不是很常見的概念, 因此記錄下.如果在這之前恰好了解過 bitmap這種數據結構就更好了。不了解也沒有關系。

bitmap 就是用bit的每一位來代表一個特殊的狀態值,或者說標簽屬性等等.舉例來說, 8位的數值, 用 0000 0001 代表 北, 0000 0010 代表南, 0000 0100 代表西 依次類推.

那么當我們拿到一串bit, 如:0100 0000 自然可以去對應的映射關系表中查找到 究竟是屬于哪一種類型, 如果我們想同時傳遞兩個數值呢?

只需要 0000 0011 這樣就可以表示 北 南 兩個方向了, 當然 至多可以表示 8個方向.

我們來試試這種表示方式:

public class Direction {
  public static final short NORTH = 1;
  public static final short SOUTH = 1 << 2;
  public static final short WEST = 1 << 3;
  public static final short EAST = 1 << 4;
  public static final short SOUTH_EAST = 1 << 8;
}

在這里我只是簡略的定義了其中5中.

那么可能會有一個問題, 既然使用 short來表示, 為什么不用 1 2 3 ... 8 來表示數據呢? 這樣我們甚至都不需要2 的 8次方, 只需要 3位就能夠表示所有數據了.

但是不妨讓我們再來想一想, 在使用 1 ~ 8 的方式中如何同時傳入多種狀態呢?

在這里是不是必須使用 一個 short[] 去接收數據?

那么用位有什么好處呢?

void array(NORTH | SOUTH | SOUTH_EAST)

在方法的調用上 可以采用這種直觀易懂且計算速度快的方式, 而在傳入值 不難發現 最終只有一個值:

1000 0011

這一個數值即表示了包含了相應的三種狀態.而這就是 java中 位域的使用方式.那么進一步來看, 當我們不再滿足 8位 甚至需要更多種狀態值的時候 可以切換到 int long 甚至于 bitmap. 接收無限位。

但僅僅是位域這種表示 我們僅僅支持 64種以下的狀態類型, 因為 java種最長的基本類型 也就只有64位了。

那么繼續來看看這種位域有什么缺陷呢?

使用int 類型 或 long類型, 沒有辦法加入一些自定義的東西, 通常情況下 在這種地方使用枚舉是更好地選擇。

否則的話所有的地方依然要使用 switch判斷的方式, 另外由于 int定義為 static final 時 本身就是編譯時常量,

如果有人依賴他, 將來即使這里的數值更新了, 比如刪掉兩三個, 即使不重新編譯, 對方的class文件依然不會出錯。 但事實上, 出錯是一種必然。

就上面的例子來說, 我們想要返回所有的String 該怎么辦?必然是 switch case return "南" 類似的方式.

那么切換成枚舉類型呢?

public enum EnumDirection {
  NORTH("north"), EAST("east"), SOUTH("south"), WEST("south");
  private final String name;
  private EnumDirection(String name) {
    this.name = name;
  }
  public String getName() {
    return this.name;
  }
}

枚舉類型的好處,不再贅述。

那與今天的主題, 位域有什么關系呢?我們知道,位域的優點 占用內存小, 表示方便, 傳遞值方便, 性能高.EnumSet, 讓我抄一段描述:

這個類實現Set接口,提供了豐富的功能,類型安全性,以及可以從任何其他Set實現中得到的互用性。但是在內部具體的實現上,每個EnumSet內容都表示為位矢量。如果底層的枚舉類型有64個或者更少的元素——大多數如此。整個EnumSet就用單個long來表示,因此它的性能比的上位域的性能。批處理,如removeAll和retainAll,都是利用位算法來實現的。就像手工替代位域實現得那樣。

是的, 是位運算.

就看一段代碼:

public boolean contains(Object e) {
  if (e == null)
    return false;
  Class<?> eClass = e.getClass();
  if (eClass != elementType && eClass.getSuperclass() != elementType)
    return false;
  return (elements & (1L << ((Enum<?>)e).ordinal())) != 0;
}

我們關注到最后一行, 如上述EnumDirection, WEST 的 ordinal() 即是4, 也就意味著 它值在這里被理解為 1 << 4

而通過 elements 傳入enumSet 的集合, 如:

EnumSet<EnumDirection> enumSet = EnumSet.of(EnumDirection.EAST, EnumDirection.NORTH);

不難獲知 enumSet 的 elements值為 0000 0011 當然 這里是 long類型, 我只寫了最后8位, 而

0000 0011 & 0000 1000 必然是等于 0的 因此 contains 返回false.

這是極其高效的方式. 而目的也正在于解決 int型 位域的種種弊端.

以上是“Java位域的示例分析”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

城市| 和田县| 壤塘县| 成武县| 耒阳市| 东乌珠穆沁旗| 财经| 合肥市| 安义县| 阜宁县| 桂东县| 宕昌县| 鹿邑县| 佛教| 新郑市| 耿马| 新安县| 隆德县| 湾仔区| 邵阳县| 南康市| 漳平市| 新余市| 灯塔市| 辽宁省| 阿克陶县| 井研县| 桐庐县| 山阳县| 辽阳县| 东丰县| 探索| 莫力| 滨州市| 吕梁市| 龙岩市| 临桂县| 阜城县| 上林县| 平罗县| 本溪市|