【问题标题】:Checking flag bits java检查标志位java
【发布时间】:2011-05-20 04:17:40
【问题描述】:

我对标志位有疑问。 我有一个 int 变量来保存标志。首先,我为该变量设置了一些标志。稍后我需要检查在该变量中设置了多少标志。但我不知道该怎么做。

【问题讨论】:

    标签: java bit-manipulation flags


    【解决方案1】:

    这是我在项目中使用的实用程序类

    public class FlagUtils {
    
    // ------------------------------------------------------------------------
    // TYPES
    // ------------------------------------------------------------------------
    
    // ------------------------------------------------------------------------
    // STATIC FIELDS
    // ------------------------------------------------------------------------
    
    // ------------------------------------------------------------------------
    // STATIC METHODS
    // ------------------------------------------------------------------------
    
    /**
     * Sets the specified flags on the source int
     *
     * @param source the source int
     * @param flag   the flags which should be set
     *
     * @return the set int
     */
    public static int setFlag(int source, int flag) {
        return source | flag;
    }
    
    /**
     * Un-sets the specified flags on the source int
     *
     * @param source the source int
     * @param flag   the flags which should be set
     *
     * @return the set int
     */
    public static int unsetFlag(int source, int flag) {
        return source & ~flag;
    }
    
    
    /**
     * Check if the flags are set on the source ints
     *
     * @param source the source int
     * @param flag   the flags which should be set
     *
     * @return the set int
     */
    public static boolean isFlagSet(int source, int flag) {
        return (source & flag) == flag;
    }
    
    /**
     * Flibs teh specified bit on the source
     *
     * @param source the source int
     * @param flag   the flags which should be set
     *
     * @return the set int
     */
    public static int flip(int source, int flag) {
        return source & ~flag;
    }
    
    /**
     * Returns the masked int
     *
     * @param source the source int
     * @param mask
     *
     * @return the set int
     */
    public static int mask(int source, int mask) {
        return source & mask;
    }
    
    
    // ------------------------------------------------------------------------
    // FIELDS
    // ------------------------------------------------------------------------
    
    // ------------------------------------------------------------------------
    // CONSTRUCTORS
    // ------------------------------------------------------------------------
    
    // ------------------------------------------------------------------------
    // METHODS
    // ------------------------------------------------------------------------
    
    // ------------------------------------------------------------------------
    // GETTERS / SETTTERS
    // ------------------------------------------------------------------------
    

    }

    【讨论】:

      【解决方案2】:

      检查是否设置了位值:

      int value = VALUE_TO_CHECK | OTHER_VALUE_TO_CHECK;
      
      if ((value & VALUE_TO_CHECK) == VALUE_TO_CHECK)
      {
          // do something--it was set
      }
      
      if ((value & OTHER_VALUE_TO_CHECK) == OTHER_VALUE_TO_CHECK)
      {
          // also set (if it gets in here, then it was defined in 
          //   value, but it does not guarantee that it was set with
          //   OR without other values. To guarantee it's only this
          //   value just use == without bitwise logic)
      }
      

      请务必注意,您不应将检查值设为 0,除非它表示 All 或 None(并且不要使用按位逻辑进行比较;只需使用 value == 0),因为任何 value & 0 始终为 0。

      【讨论】:

      • 这里我没有标记(如 VALUE_TO_CHECK)。我有另一个包含一些标志的变量。所以我需要找到 A 包含 B 中是否存在的所有标志。
      • @Naga raju 所以请澄清你的问题。
      • 如果你有一个设置了一堆标志的值:int A = flag1 | flag3 | flag15;,并且你想看看它是否包含来自B的所有值:int B = flag3 | flag15;,然后B VALUE_TO_CHECK在上面的代码中:if (A & B == B)(忽略可怕的变量名)。另外,由于听起来您对此感到困惑,因此您应该参考垃圾神的答案并购买参考书(乔什·布洛赫(Josh Bloch)撰写)。作为 Java 开发人员,这是一本最好的书。
      • 你需要另一组括号来编译它,即 if ((value & VALUE_TO_CHECK) == VALUE_TO_CHECK),和 (value & OTHER_VALUE_TO_CHECK) 相同
      • if 语句下一行的大括号? 颤抖 :P
      【解决方案3】:

      如果要检查a是否设置了b中的所有标志位,可以检查为:

      (a & b) == b
      

      【讨论】:

        【解决方案4】:

        我正在使用以下内容:

        public class BitFlags
        {
            public static boolean isFlagSet(byte value, byte flags)
            {
                return (flags & value) == value;
            }
        
            public static byte setFlag(byte value, byte flags)
            {
                return (byte) (flags | value);
            }
        
            public static byte unsetFlag(byte value, byte flags)
            {
                return (byte) (flags & ~value);
            }
        }
        

        但是,如果您不需要它“低级”,建议使用 EnumSets 来代替类型安全的额外好处。

        【讨论】:

        • 不应该是return (flags & value) == flags;而不是return (flags & value) == value;吗?
        【解决方案5】:

        另外,考虑使用EnumSet 代替位字段。另见Bloch, Item 32

        附录:具体example

        枚举集还为传统的位标志提供了丰富的类型安全替代:

        EnumSet.of(Style.BOLD, Style.ITALIC);
        

        特别注意从AbstractSetAbstractCollection 继承的便捷方法。

        【讨论】:

        • 如何使用它来替换位域?我没能成功。
        • 我不确定你在哪里遇到了麻烦;更多示例请见here
        猜你喜欢
        • 1970-01-01
        • 2019-12-22
        • 2011-03-09
        • 1970-01-01
        • 1970-01-01
        • 2011-11-09
        • 2011-02-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多