une - set java




Quel type de collection Java dois-je utiliser pour cela? (3)

Je suis relativement nouveau à Java et j'ai du mal à comprendre les différences entre les différentes collections. J'ai une liste de 19 ressources. Chaque ressource reçoit une couleur hexadécimale. Je veux obtenir une ressource aléatoire avec sa couleur et utiliser cette ressource avec mon code. Une fois que j'ai terminé avec la ressource actuelle, je veux l'enlever de la liste afin que seulement un certain nombre de ressources soient utilisées.

Dois-je utiliser un dictionnaire, une carte ou une table de hachage? Ou tous les autres qui me manquent.


Blockquote

Si vous avez besoin d'une commande aléatoire, vous pouvez choisir l'objet List.

List<String> resourceMap = new CopyOnWriteArrayList<>();
          resourceMap.add("hex1");
          resourceMap.add("hex2");
          resourceMap.add("hex3");
          resourceMap.add("hex4");
          Collections.shuffle(resourceMap);
          resourceMap.forEach(resource->{
              resourceMap.remove(resource);
          });

Ce que vous pouvez faire, c'est stocker vos ressources dans une List , puis le permuter aléatoirement grâce à Collections.shuffle(List<?> list) ou shuffle(List<?> list, Random rnd) , et enfin appeler iterator() sur le liste résultante pour obtenir une instance de Iterator que vous pourriez stocker dans un champ membre pour pouvoir itérer sur votre liste (grâce à hasNext() / next() ) et supprimer votre ressource une fois fait avec remove() .

Voici un pseudo code utilisant String comme ressource juste pour montrer l'idée:

// Create a read/write list (Arrays.asList returns a read-only list)
List<String> resources = new ArrayList<>(Arrays.asList("1", "2", "3"));
System.out.printf("Initial state = %s%n", resources);
Collections.shuffle(resources);
System.out.printf("Permuted List = %s%n", resources);
Iterator<String> iterator = resources.iterator();
if (iterator.hasNext()) {
    String resource = iterator.next();
    // do something
    iterator.remove();
    System.out.printf("After remove = %s%n", resources);
}

Sortie:

Initial state = [1, 2, 3]
Permuted List = [3, 1, 2]
After remove = [1, 2]

NB: Cette approche est logique dans votre cas car vous avez une petite liste, notez que si vous avez une grande liste et que vous avez l'intention d'en récupérer seulement une petite partie, vous devriez envisager d'utiliser un Random pour obtenir aléatoirement l'index du next element (en utilisant nextInt(int bound) avec list.size() en paramètre) get (en utilisant get(int index) ) et remove (en utilisant remove(int index) ) au lieu d'utiliser Collections.shuffle(List<?> list) car cela entraînerait un surcoût.

ArrayList ne fonctionnerait pas car j'ai besoin d'affecter la couleur (valeur) à la ressource (clé)

Oui cela peut fonctionner si vous utilisez une List d'une classe wrapper qui contiendra à la fois votre couleur et votre ressource (par exemple AbstractMap.SimpleImmutableEntry ou simplement une classe personnalisée). C'est assez bon car vous ne semblez pas avoir besoin de récupérer la couleur par ressource. Si vous le faites, vous pouvez simplement avoir une Map avec une ressource en tant que clé et couleur comme valeur et utiliser la new ArrayList<>(map.keySet()) pour initialiser votre liste de ressources, vous pourrez ensuite appliquer ce qui est proposé précédemment cette réponse.


Si vous voulez rechercher (obtenir) une ressource en fonction de son utilisation hexadécimale

// Initialize
Map<String, Resource> resourceMap = new HashMap<>();
resourceMap.put("hex1", hex1Resource);
resourceMap.put("hex2", hex3Resource);
resourceMap.put("hex3", hex3Resource);

// Get specific
Resource hex2Resource = resourceMap.get("hex2");
resourceMap.remove("hex2");

Si vous voulez rechercher une ressource de manière aléatoire, il y a 2 options

  • Utiliser la liste (cela permet les doublons)
  • Utiliser Set (ne stocke que des valeurs uniques)

Utilisation de listes

// Initialize
List<Resource> list = new ArrayList<>();
list.add(resource1);
list.add(resource2);
list.add(resource3);

// Get random
Random rand = new Random();
Resource randomResource = list.get(rand.nextInt(list.size()));

// Delete the element from list
list.remove(randomResource);

Utiliser des ensembles

// Initialize
Set<Resource> set = new HashSet<>();
set.add(resource1);
set.add(resource2);
set.add(resource3);

// Convert to List, since Set does not have get(int) method. 
List<Resource> list = new ArrayList<>(set);

// Get random
Random rand = new Random();
Resource randomResource = list.get(rand.nextInt(list.size()));

// Delete the element from list
list.remove(randomResource);

Remarque : Dans les deux cas ci-dessus, la classe Resource devra implémenter les méthodes equals et hashcode pour que la liste / l'ensemble puisse comparer les éléments et fonctionner correctement. Voir Java est égal à et hashcode

Mise à jour : les ensembles n'ont pas la méthode get (int). Mise à jour le code pour résoudre ce problème.





collections