web-dev-qa-db-fra.com

Vérification des bits d'indicateur java

J'ai un problème avec les bits de drapeau. J'ai une variable int pour contenir les drapeaux. J'ai d'abord mis quelques indicateurs sur cette variable. Plus tard, j'ai besoin de vérifier combien de drapeaux ont été définis dans cette variable. Mais je ne sais pas le faire.

45
Nagaraju

Pour vérifier si une valeur de bit est définie:

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

Il est important de noter que vous ne devriez pas avoir une valeur vérifiée comme 0 à moins qu'elle ne représente Tout ou Aucun (et n'utilisez pas de logique au niveau du bit pour comparer; utilisez simplement value == 0) car tout value & 0 est TOUJOURS 0.

80
pickypg

Envisagez également d'utiliser un EnumSet au lieu des champs de bits. Voir aussi Bloch, article 32 .

Addendum: Comme concret exemple :

Les ensembles d'énumérations fournissent également un remplacement riche et sûr pour les indicateurs de bits traditionnels:

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

Notez en particulier les méthodes pratiques héritées de AbstractSet et AbstractCollection.

33
trashgod

Si vous voulez vérifier si a a tous les bits de drapeau dans b set, vous pouvez le vérifier comme:

(a & b) == b
19
Ates Goral

J'utilise ce qui suit:

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

Cependant, si vous n'en avez pas besoin "bas niveau", il est conseillé d'utiliser EnumSets à la place pour l'avantage supplémentaire de sécurité de type.

10
BullyWiiPlaza