Frage

Ist es bei einer auf 1 Byte codierten binären Zeichenfolge möglich, einige der Bits dieses Byte in einen Umlaufwert zuzuordnen?
ZB: Angenommen, ich möchte mein Feld in dieses Thema schneiden:

  • bit1 und bit2 = field1
  • bit3 = field2
  • bit4 = field3
  • bit5 = field4
  • Andere Teile sind ungenutzt

Wie könnte ich das zuordnen, um zu sagen:

public enum MyEnum {
    FIELD1, FIELD2, FIELD3, FIELD4;

    private static final EnumSet<MyEnum> ALLFIELDS = EnumSet.allOf(MyEnum.class);

}

Ich versuche, diese Enum -Werte mit einer Bitmaske herauszufiltern. Dafür habe ich die folgende Methode gemacht:

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;
}

Dies funktioniert gut, solange meine Enum -Felder ein einziges Stück darstellen, aber ich kann nicht herausfinden, wie ich sie in einem einzelnen Feld kombinieren kann. Tut mir leid, wenn das offensichtlich aussieht, aber dies ist das erste Mal, dass ich Daten auf Bit -Ebene manipuliere ...

Bearbeiten Kommentare: Ich habe die Feldstruktur bearbeitet, um das darzustellen, was ich wirklich habe. Das einzige Feld, das mehr als 1 Bit umfasst, ist Field1. Basierend auf dem Vorhandensein von Bit1 und Bit2 weise ich Feld1 eine Gewichtsvariable zu.

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;
        }

    }


}

Hier ist die schmutzige Lösung, die ich mir vorerst ausgedacht habe, aber ich mag es nicht wirklich mit all diesen wenn auch Aussagen. Wenn jemand eine bessere Lösung hat, würde ich mich freuen, dies zu ändern ;-)

Vielen Dank !

War es hilfreich?

Lösung

Ich bin mir nicht ganz sicher, was du willst. Dies könnte von Interesse sein:

import java.util.*;
enum Field {
    field1((byte) 0xc0) {
        int filter_(byte mask) { // you may want this one to be different
            return mask & this.mask;
        }
    },
    field2((byte) 0x20), field3((byte) 0x10), field4((byte) 0x08);
    Field(byte mask) {
        this.mask = mask;
    }
    int filter_(byte mask) {
        return mask & this.mask;
    }
    static EnumSet<Field> filter(byte mask) {
        final EnumSet<Field> fields = EnumSet.noneOf(Field.class);
        for (Field field : values())
            if (field.filter_(mask) != 0) fields.add(field);
        return fields;
    }
    final byte mask;
}
public class Main {
    public static void main(String[] args) {
        for(Field field:Field.values()) {
            System.out.println(Field.filter(field.mask));
        }
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top