1 バイトでコード化されたバイナリ文字列が与えられた場合、そのバイトのビットのいくつかを列挙値にマップすることは可能ですか?
例:フィールドをこれに切り取りたいとします:
- bit1 および bit2 = フィールド 1
- ビット 3 = フィールド 2
- ビット 4 = フィールド 3
- ビット 5 = フィールド 4
- 他のビットは未使用
どうすればそれを次のようにマッピングできますか:
public enum MyEnum {
FIELD1, FIELD2, FIELD3, FIELD4;
private static final EnumSet<MyEnum> ALLFIELDS = EnumSet.allOf(MyEnum.class);
}
私がやろうとしているのは、ビットマスクを使用してこれらの列挙値を除外することです。そのために、次の方法を実行しました。
public static <E extends Enum<E>> EnumSet<E> filterWithBitMask(EnumSet<E> set, int bitmask) {
List<E> kept = new ArrayList<E>();
for (E property : set) {
if ((bitmask & (1 << ((Enum<E>) property).ordinal())) != 0) {
kept.add(property);
}
}
EnumSet<E> selectedProperties = set.clone();
selectedProperties.retainAll(kept);
return selectedProperties;
}
列挙型フィールドが単一のビットを表している限り、これは正常に機能しますが、それらを単一のフィールドに結合する方法がわかりません。当たり前のようで申し訳ありませんが、ビットレベルでデータを操作するのはこれが初めてです...
コメントの編集 : フィールド構造を編集して、実際に持っているものを表現しました。したがって、1 ビットを超えるフィールドは field1 だけです。bit1 と bit2 の存在に基づいて、重み変数を field1 に割り当てます。
public enum MyByte {
BIT_1, BIT_2, BIT_3, BIT_4, BIT_5;
private static final EnumSet<MyByte> ALLPROPERTIES = EnumSet.allOf(MyByte.class);
public static EnumSet<Fields> getValues(int bitmask) {
EnumSet<MyByte> selectedBits = filterWithBitMask(ALLPROPERTIES, bitmask);
int weight = 0;
EnumSet<Fields> fields = null;
if (selectedBits.contains(BIT_1))
weight += 1;
if (selectedBits.contains(BIT_2))
weight += 2;
if (selectedBits.contains(BIT_1) || selectedBits.contains(BIT_2))
fields = EnumSet.of(Fields.FIELD1.setValue(weight));
if (selectedBits.contains(BIT_3)) {
if (fields != null)
fields.add(Fields.FIELD2);
else fields = EnumSet.of(Fields.FIELD2);
}
if (selectedBits.contains(BIT_4)) {
if (fields != null)
fields.add(Fields.FIELD3);
else fields = EnumSet.of(Fields.FIELD3);
}
if (selectedBits.contains(BIT_5)) {
if (fields != null)
fields.add(Fields.FIELD4);
else fields = EnumSet.of(Fields.FIELD4);
}
return fields;
}
public enum Fields {
// BIT_1 and BIT_2
FIELD1,
// BIT_3
FIELD2,
// BIT_4
FIELD3,
// BIT_5
FIELD4;
private int value;
public Fields setValue(int i) {
this.value = i;
return this;
}
}
}
ここに私が今思いついた汚い解決策がありますが、これらすべての if ステートメントではあまり好きではありません。誰かがより良い解決策を持っている場合は、これを変更して喜んでいます;-)
ありがとう !