web-dev-qa-db-fra.com

Comment utiliser Java.Set

J'essaie de le faire fonctionner pendant un certain temps, mais je n'arrive pas à le comprendre. J'ai un objet Tower construit de Block's. Je l'ai déjà fait fonctionner en utilisant des tableaux, mais je voulais apprendre les ensembles. J'aimerais obtenir des fonctionnalités similaires à ceci:

public class Tower {


public Tower(){
}

public Tower add(Block k1){

    //(...)
    //if block already in tower, return "Block already in tower"
}

public Tower delete(Block k1){

    //(...)
    //if block already dleted, show "No such block in tower"
}

}

Quelqu'un m'a donné du code, mais je reçois constamment des erreurs lorsque j'essaie de l'utiliser:

Set<Block> tower = new HashSet<Block>();

boolean added = tower.add( k1 );
if( added ) {
System.out.println("Added 1 block.");
} else {
System.out.println("Tower already contains this block.");
}

Comment l'implémenter?

15
owca

La première chose que vous devez étudier est l'API Java.util.Set .

Voici un petit exemple d'utilisation de ses méthodes:

    Set<Integer> numbers = new TreeSet<Integer>();

    numbers.add(2);
    numbers.add(5);

    System.out.println(numbers); // "[2, 5]"
    System.out.println(numbers.contains(7)); // "false"

    System.out.println(numbers.add(5)); // "false"
    System.out.println(numbers.size()); // "2"

    int sum = 0;
    for (int n : numbers) {
        sum += n;
    }
    System.out.println("Sum = " + sum); // "Sum = 7"

    numbers.addAll(Arrays.asList(1,2,3,4,5));
    System.out.println(numbers); // "[1, 2, 3, 4, 5]"

    numbers.removeAll(Arrays.asList(4,5,6,7));
    System.out.println(numbers); // "[1, 2, 3]"

    numbers.retainAll(Arrays.asList(2,3,4,5));
    System.out.println(numbers); // "[2, 3]"

Une fois que vous êtes familiarisé avec l'API, vous pouvez l'utiliser pour contenir des objets plus intéressants. Si vous ne vous êtes pas familiarisé avec les contrats equals et hashCode , c'est déjà le bon moment pour commencer.

En un mot:

  • @Override les deux ou aucun; jamais juste un. (très important, car il doit satisfaire la propriété: a.equals(b) == true --> a.hashCode() == b.hashCode()
    • Soyez prudent avec l'écriture de boolean equals(Thing other) à la place; ce n'est pas un bon @Override.
  • Pour les références non nulles x, y, z, equals doit être:
    • réflexif: x.equals(x).
    • symétrique: x.equals(y) si et seulement si y.equals(x)
    • transitif: si x.equals(y) && y.equals(z), alors x.equals(z)
    • cohérent: x.equals(y) ne doit pas changer sauf si les objets ont muté
    • x.equals(null) == false
  • Le contrat général pour hashCode est le suivant:
    • cohérent: retourne le même nombre sauf si une mutation s'est produite
    • compatible avec equals: si x.equals(y), alors x.hashCode() == y.hashCode()
      • à strictement parler, l'inégalité d'objet ne nécessite pas l'inégalité de code de hachage
      • mais l'inégalité du code de hachage nécessite nécessairement l'inégalité des objets
  • Ce qui compte comme mutation doit être cohérent entre equals et hashCode.

Ensuite, vous voudrez peut-être imposer un ordre de vos objets. Vous pouvez le faire en faisant votre type implémente Comparable , ou en fournissant un Comparator séparé.

Avoir l'un ou l'autre facilite le tri de vos objets (Arrays.sort, Collections.sort(List)). Il vous permet également d'utiliser SortedSet, comme TreeSet.


Lectures supplémentaires sur stackoverflow:

54
polygenelubricants

Avez-vous remplacé equals et hashCode dans la classe Block?

ÉDITER:

Je suppose que vous voulez dire que cela ne fonctionne pas au moment de l'exécution ... vouliez-vous dire cela ou au moment de la compilation? Si compiler le temps, quel est le message d'erreur? S'il se bloque à l'exécution, quelle est la trace de la pile? S'il compile et s'exécute mais ne fonctionne pas correctement, les paramètres égal et hashCode sont le problème probable.

2
TofuBeer

Il est difficile de répondre à cette question avec les informations fournies. Rien ne semble particulièrement mal avec la façon dont vous utilisez HashSet.

Eh bien, je suppose que ce n'est pas un problème de compilation et, lorsque vous dites "obtenir des erreurs", vous voulez dire "ne pas obtenir le comportement que vous voulez".

Je vais également sortir sur un membre et suggérer que peut-être votre bloc est égal à une méthode hashCode ne sont pas correctement remplacées.

1
MaxGuernseyIII

Puisqu'il s'agit d'un HashSet, vous devrez remplacer hashCode et égal à les méthodes . http://preciselyconcise.com/Java/collections/d_set.php contient un exemple expliquant comment implémenter hashCode et les méthodes égales

0
Sai Sunder