2011-09-07 5 views
1

1 바이트에 코딩 된 2 진 문자열을 감안할 때, 해당 바이트의 여러 비트를 열거 형 값으로 매핑 할 수 있습니까?
예 : :이에 내 필드를 잘라한다고 가정 : = FIELD2 EnumSet을 사용하여 단일 필드에서 2 비트를 결합하는 방법은 무엇입니까?

  • 비트 4

    • 비트 1 및 비트 2 = 필드 1
    • 비트 3 = FIELD3
    • 비트 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 문으로 정말 좋아하지 않습니다. 누군가에게 더 좋은 해결책이 있다면, 이것을 바꿔 드리겠습니다. ;-)

    고마워요!

  • +1

    왜 필드 3에 3 비트를 사용하고 있습니까? field3가 최대 8 개의 서로 다른 값을 가질 수 있다는 것을 의미합니까? –

    +1

    field1이 2 비트이면 4 개의 가능한 값 (00, 01, 10, 11)을 보유 할 수 있습니다. 열거 형은 4 비트 열거 형 값을 정의하지 않는 한 2 비트의 각 조합에 대해 하나씩 적절한 표현이 아닙니다. 필드 3 및 필드 4에 대한 내용입니다. –

    +0

    @ 미스터 스미스 예 – Philippe

    답변

    2

    당신이 뭘 원하는지 확실하지 않습니다. 관심사 일 수 있습니다.

    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)); 
         } 
        } 
    } 
    
    관련 문제