72 votes

Remplissage d'un tableau booléen en Java

En tant que codeur Java assez novice, je me suis lancé un défi de taille : essayer d'écrire une simple aventure textuelle. Sans surprise, j'ai déjà rencontré des difficultés !

J'essaie de donner à ma classe Location une propriété pour stocker les sorties qu'elle contient. Pour ce faire, j'ai utilisé un tableau de booléens, qui contient essentiellement des valeurs vrai/faux représentant chaque sortie. Je ne suis pas entièrement convaincu que

a) c'est la manière la plus efficace de procéder et

b) que j'utilise le bon code pour remplir le tableau.

J'apprécierais tout commentaire, même s'il s'agit d'une révision complète du code !

Actuellement, lors de l'instanciation d'un emplacement, je génère une chaîne de caractères que j'envoie à la méthode setExits :

    String e = "N S U";
    secretRoom.setExits(e);

Dans la classe Location, setExits ressemble à ceci :

public void setExits(String e) {
    if (e.contains("N"))
        bexits[0] = true;
    else if (e.contains("W"))
        bexits[1] = true;
    else if (e.contains("S"))
        bexits[2] = true;
    else if (e.contains("E"))
        bexits[3] = true;
    else if (e.contains("U"))
        bexits[4] = true;
    else if (e.contains("D"))
        bexits[5] = true;
}

Je vais être honnête, je pense que cela semble particulièrement maladroit, mais je n'ai pas trouvé d'autre moyen de le faire. Je ne suis pas non plus tout à fait sûr de savoir comment écrire la méthode getExits...

Toute aide serait la bienvenue !

127voto

gexicide Points 11040

Le plus efficace y manière expressive est la suivante :

Utilisez enum comme sorties et utiliser un EnumSet pour les stocker. EnumSet est efficace Set qui utilise un champ de bits pour représenter les constantes de l'enum.

Voici comment vous pouvez le faire :

public enum Exit { North, West, South, East, Up, Down; }

EnumSet<Exit> set = EnumSet.noneOf(Exit.class); // An empty set.

// Now you can simply add or remove exits, everything will be stored compactly

set.add(Exit.North); // Add exit
set.contains(Exit.West); // Test if an exit is present
set.remove(Exit.South); //Remove an exit

L'ensemble d'énuméros stockera toutes les sorties dans un seul et unique long en interne, de sorte que votre code est expressif, rapide et économise beaucoup de mémoire.

29voto

Ross Drew Points 3562

Y a-t-il une raison pour laquelle vous faites cela avec String et ne passent pas dans booleans c'est-à-dire

public void setExits(boolean N, boolean E, boolean S, boolean W, boolean U, boolean D) 

Ou avoir setters ?

public void setNorthOpen(boolean open)
{
  bexits[4] = open;
}

Deuxièmement, pourquoi stocker les sorties sous la forme d'un tableau de booléens, il s'agit d'un petit ensemble fini.

boolean N,S,E,W,U,D;

Comme cela, vous n'avez pas besoin de savoir à quel numéro du tableau correspond chaque direction.

Aussi

C'est une réponse correcte (même si elle n'est pas complètement optimale comme celle de @gexicide) mais j'encourage vivement quiconque à regarder les autres réponses ici pour un regard intéressant sur la façon dont les choses peuvent être faites en Java de différentes manières.

Pour une référence future

Le code qui fonctionne appartient à Examen du code et non Stack Overflow. Bien que, comme @kajacx l'a souligné, ce code ne devrait pas -en fait- fonctionner.

15voto

kajacx Points 2690

OK, tout d'abord, votre setExits() ne fonctionnera pas comme prévu, les if-elseif enchaînés exécuteront au maximum une branche de code, par exemple :

if (e.contains("N"))
    bexits[0] = true;
else if (e.contains("W"))
    bexits[1] = true;

Même si e contient à la fois N y W seulement bexits[0] sera définie. De plus, cette méthode n'ajoutera que des sorties (par exemple en appelant setExits("") ne supprimera pas les sorties existantes.

Je changerais cette méthode en :

bexits[0] = e.contains("N");
bexits[1] = e.contains("W");
...

De plus, je ne me souviendrais certainement pas que le nord est à l'indice 0, l'ouest à l'indice 1, ... donc une pratique courante est de nommer vos indices en utilisant des constantes statiques finales :

public static final int NORTH = 0;
public static final int WEST = 1;
...

Ensuite, vous pouvez écrire dans votre setExits méthode :

bexits[NORTH] = e.contains("N");
bexits[WEST] = e.contains("W");
...

(beaucoup plus lisible)

Enfin, si vous souhaitez que votre code soit encore mieux organisé, vous pouvez créer un fichier de type Exits classe représentant les sorties disponibles, et soutenue par un tableau de booléens. Ensuite, à l'endroit où vous créez votre chaîne, vous pouvez créer cette classe à la place et vous épargner le travail de génération puis d'analyse d'une chaîne.

EDITAR:

comme le répond @gexicide, il existe une classe très pratique EnumSet qui serait probablement meilleur pour représenter les sorties qu'un tableau de booléens.

9voto

Tim B Points 19851

El EnumSet Je voulais juste ajouter une autre chose pour l'avenir, lorsque vous commencerez à vous demander non seulement si vous pouvez déménager, mais aussi où vous allez.

Ainsi que EnumSet vous avez également EnumMap .

Si vous définissez une classe/interface de salle, alors à l'intérieur de la classe de salle vous pouvez avoir

Map<Direction, Room> exits = new EnumMap<>(Direction.class);

Vous pouvez maintenant ajouter vos liens dans la carte comme suit :

exits.put(Direction.NORTH, theRoomNorthOfMe);

Votre code de déplacement entre les pièces peut alors être très général :

Room destination=currentRoom.getExit(directionMoved);

if (destination == null) {
    // Cannot move that way
} else {
    // Handle move to destination
}

7voto

niekname Points 109

Je créerais un enum Exit et dans la classe d'emplacement, je définirais simplement une liste d'objets Exit.

donc ce serait quelque chose comme :

public enum Exit { N, S, E, W, U, D }

List<Exit> exits = parseExits(String exitString);
location.setExits(exits);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X