Implementing a bitfield using java enums

后端 未结 5 944
南笙
南笙 2020-12-02 11:03

I maintain a large document archive and I often use bit fields to record the status of my documents during processing or when validating them. My legacy code simply uses sta

相关标签:
5条回答
  • 2020-12-02 11:38

    A slightly better way would be to store the result of 1 << this.ordinal() in a field when the enum values are constructed. This way, you don't have to provide each value manually, and the flag is only computed once.

    public enum StatusFlag {
    
      DOCUMENT_STATUS_NOT_DEFINED,
      DOCUMENT_STATUS_OK, 
      DOCUMENT_STATUS_MISSING_TID_DIR,
      DOCUMENT_STATUS_MISSING_TIF_FILE,
      DOCUMENT_STATUS_MISSING_PDF_FILE,
      DOCUMENT_STATUS_MISSING_OCR_FILE,
      DOCUMENT_STATUS_PAGE_COUNT_TIF,
      DOCUMENT_STATUS_PAGE_COUNT_PDF,
      DOCUMENT_STATUS_UNAVAILABLE;
    
      public final int flag;
    
      StatusFlag() { 
        this.flag = 1 << this.ordinal();
      } 
    }
    

    EDIT: it could be useful to have isFlagSet method as well.

    0 讨论(0)
  • 2020-12-02 11:51

    your approach is exactly the way to do it.

    0 讨论(0)
  • 2020-12-02 11:51

    Don't give your enums values. Use an EnumSet to combine them, and use Enum.ordinal() when persisting in order to convert to/from a single integer. You might also find Class.getEnumConstants() useful when reconstructing the set from the integer.

    0 讨论(0)
  • 2020-12-02 11:51

    I have made a complete library for this problem: http://claude-martin.ch/enumbitset/

    The main goal was to store sets of enum types in bitfields. But it also supports other types.

    With this you would not need any extra methods like your "getStatusFlags()". It can be used on any existing enum type simply by adding the interface EnumBitSetHelper (it is used like a "trait"). Each enum constant can then create an "EnumBitSet" which has all methods of Java's EnumSet and BitSet. Then you can work with these sets of enum constants and convert them to bitfield values.

    It supports many formats such as BigInteger and long to easily store the value into a bit field. But note that this only works with Java version 8 and newer.

    0 讨论(0)
  • 2020-12-02 12:03

    Instead of defining constructor parameters, you could simply use the internal ordinal() value to calculate this.

    public enum StatusFlag {
    
        DOCUMENT_STATUS_NOT_DEFINED,
        DOCUMENT_STATUS_OK, 
        DOCUMENT_STATUS_MISSING_TID_DIR,
        DOCUMENT_STATUS_MISSING_TIF_FILE,
        DOCUMENT_STATUS_MISSING_PDF_FILE,
        DOCUMENT_STATUS_MISSING_OCR_FILE,
        DOCUMENT_STATUS_PAGE_COUNT_TIF,
        DOCUMENT_STATUS_PAGE_COUNT_PDF,
        DOCUMENT_STATUS_UNAVAILABLE;
    
    
        public long getStatusFlagValue(){
            return 1 << this.ordinal();
        } 
    
    }
    

    Please note that now you should abstain from reordering, inserting (other than at the end) or deleting entries, otherwise the flag values will change, and the meaning of your database contents will change.

    0 讨论(0)
提交回复
热议问题