Bitset

Collection des bits en Java

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

L'article précédent consacré à des collections en Java a présenté les éléments qu'on est censés d'utiliser le plus fréquemment. L'un des usages plus rares des collections peut concerner les bits. Mais même pour ça, Java a prévu un outil spécifique.

La manipulation des collections des bits peut être réalisée avec la classe java.util.BitSet. La taille de cette collection peut être augmentée en fonction du besoin. Son fonctionnement ressemble donc à celui des Vectors en Java. Un bit faisant partie de ce Vector peut être soit vrai (true), soit faux (false). Les bits sont indexés dans la collection avec des entiers non-négatifs.

On a déjà traité le sujet des bits en Java dans un autre article. Regardons maintenant ce qu'on peut faire avec une collection des bits sur le même use case que dans l'article mentionné :

import java.util.BitSet;

public class BitSetExemple {
    public static void main(String[] args) {
        BitSet access = new BitSet();
        access.set(4, true);
        access.set(16, true);
        access.set(32, true);
        access.set(64, true);
    
        BitSet users = new BitSet();
        users.set((4 | 16), true);
        users.set((4 | 32), true);
        users.set((4 | 16 | 32), true);
        users.set((4 | 16 | 64), true);
        users.set(4, true);
        users.set(16, true);
    
        System.out.println("Users set size is " + users.size());
        System.out.println("Users set length is " + users.length());
        System.out.println("Access set size is " + access.size());
        System.out.println("Access set length is " + access.length());
        for (int i = 0; i < users.size(); i++) {
            System.out.println("Getting " + (i+1) + " user with bits " + users.get(i));
        }
        System.out.println("Crossing access and users BitSets " + access.intersects(users));
        access.and(users);
        System.out.println("Getting access BitSet after AND operation : " + access);
        access.or(users);
        System.out.println("Getting access BitSet after OR operation : " + access);
        access.xor(users);
        System.out.println("Getting access BitSet after XOR operation : " + access);
        access.andNot(users);
        System.out.println("Getting access BitSet after ANDNOT operation : " + access);
        access.or(users);
        System.out.println("Getting access BitSet after OR operation : " + access);
    }
}

Voici le résultat affiché (... signifient le même résultat - false, pour la chiffre incrémenté) :

Users set size is 128
Users set length is 85
Access set size is 128
Access set length is 65
...
Getting 4 user with bits true
Getting 5 user with bits false
...
Getting 15 user with bits false
Getting 16 user with bits true
Getting 17 user with bits false
...
Getting 35 user with bits false
Getting 36 user with bits true
Getting 37 user with bits false
...
Getting 51 user with bits false
Getting 52 user with bits true
Getting 53 user with bits false
...
Getting 83 user with bits false
Getting 84 user with bits true
Getting 85 user with bits false
...
Getting 128 user with bits false
Crossing access and users BitSets true
Getting access BitSet after AND operation : {4, 16}
Getting access BitSet after OR operation : {4, 16, 20, 36, 52, 84}
Getting access BitSet after XOR operation : {}
Getting access BitSet after ANDNOT operation : {}
Getting access BitSet after OR operation : {4, 16, 20, 36, 52, 84}

Les résultats paraissent un peu incohérents ? Oui, length() ne retourne pas le nombre d'éléments dans la collection. Cette méthode renvoie sa valeur la plus grande additionée à 1. Concernant size(), elle ne calcule pas non plus la longueur de la collection des bits. Cette fonction se charge de retourner le nombre des bits de l'espace occupé. On peut remarquer que le chiffre (128) correspond à la n^2 la plus proche du chiffre maximal compris dans la collection.

Concernant les méthodes suivantes, elles ressemblent énormément à celles utilisées dans les opérations sur les bits. On signale donc que l'instruction AND reprend les valeurs placées dans les deux collections comparées.

L'opération OR récupère les valeurs qui se trouvent soit dans la première, soit dans la deuxième collection.

Quant à andNot, elle vide la collection si des valeurs correspondantes sont trouvées dans l'autre.

En ce qui concerne xor, elle exécute OR< exclusif, où 1 est retourné si l'un des éléments comparés est 1 et l'autre 0. Si les deux bits sont différents, le résultat est 0.

TODO => peut-être voir et expliquer encore plus le xor and andNot - surtout voir pourquoi cela ne marche pas sur nos exemples

Bartosz KONIECZNY Classes

Une question ? Une remarque ?

*

*

Un conseil Symfony2

Comment valider les checkboxes avec Symfony2 ?

La validation des checkboxes sous Symfony2 se déroule avec une contrainte appelée ChoiceConstraint.

Voici l'exemple de l'utilisation:

$metadata->addPropertyConstraint('orderPreferedGift', new Choice(array('choices' => Gifts::getGiftTypes(true), 'multiple' => true, 'min' => 1,  'multipleMessage' => "Veuillez choisir au moins un type de cadeau", 'groups' => array('validationGroup'))));


Cette contrainte est très puissante. On peut déterminer par exemple la quantité des champs minimale ou maximale à cocher par utilisateur. Il est également possible de vérifier le types des valeurs.