Javaビットドメイン

3150 ワード

Javaビットドメイン
この概念はEffective Javaで知るものであり、ビットドメインの代わりにEnumSetによって表現することができる.
あまり一般的な概念ではないので、記録します.これまでbitmapというデータ構造をよく知っていたらもっとよかったのに.知らなくても大丈夫です.bitmapはbitの各ビットで特殊な状態値、あるいはラベル属性などを表す.例えば、8ビットの数値は、北を0000,0001、南を0000,西を0000,0100で順に類推する.では、0100 0000などのbitの列を手に入れると、対応するマッピング関係テーブルでどのタイプに属しているのかを見つけることができます.もし私たちが2つの数値を同時に伝えたいならば.0000 0011だけで北と南の2つの方向を表すことができ、もちろん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)
は、メソッドの呼び出しにおいて、このような直感的で分かりやすく、計算速度が速い方式を採用することができるが、入力値において、最終的には1つの値しかないことを発見するのは難しくない:
1000 0011
という数値は、対応する3つの状態を含むことを示す.これがjavaにおけるビットドメインの使用方法である.さらに、8ビット以上の状態値を満たすことなくint longまたはbitmapに切り替えることができる.無限ビットを受信します.しかし、ビットドメインだけを表すと、java種の最も長い基本タイプは64ビットしかないため、64種類以下のステータスタイプしかサポートされていません.では、このビットドメインにどんな欠陥があるか見てみましょう.intタイプやlongタイプを使用すると、カスタマイズされたものを加えることはできません.通常、このような場所で列挙を使用するのがより良いです.そうでなければすべての場所でswitch判断の方式が用いられる.またintがstatic finalと定義されている場合自体がコンパイル時定数であるため、誰かが彼に依存している場合、将来ここの数値が更新されても、例えば2、3つ削除されても、再コンパイルしなくても相手の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 enumSet = EnumSet.of(EnumDirection.EAST, EnumDirection.NORTH);
はenumSetのelements値が0000 0011であることを知るのは難しくありません.もちろん、ここはlongタイプです.私は最後の8ビットしか書いていません.
0000 0011 & 0000 1000       0     contains   false.
これは極めて効率的な方法である.目的はint型ビットドメインの様々な弊害を解決することにある.