Question

J'ai une liste d'objets à trier en fonction des propriétés de l'un de leurs champs. J'ai entendu dire que SortedMap et les comparateurs sont le meilleur moyen de le faire.

  1. Dois-je implémenter Comparable avec la classe en cours de tri ou créer une nouvelle classe?
  2. Comment instancier-t-on SortedMap et passe-t-il dans le comparateur?
  3. Comment fonctionne le tri? Va-t-il tout trier automatiquement au fur et à mesure que de nouveaux objets sont insérés?

MODIFIER: Ce code me donne une erreur:

private TreeMap<Ktr> collection = new TreeMap<Ktr>();

(Ktr implémente Comparator<Ktr>). Eclipse indique qu'il attend quelque chose comme TreeMap<K, V>, le nombre de paramètres que je fournis est donc incorrect.

Était-ce utile?

La solution

  1. La méthode la plus simple consiste à implémenter Comparable avec vos objets existants, bien que vous puissiez créer un Comparator et le transmettre au SortedMap.
    Notez que this et new TreeMap<MyObject>() sont deux choses différentes; une classe implémentant Maps compare TreeMap à un autre objet, tandis qu'une classe implémentant Collections.sort compare deux autres objets.
  2. Si vous implémentez Comparator<MyObject>, vous n'avez rien besoin de spécial dans le constructeur. Il suffit d'appeler Collections.sort(List, Comparator). ( Modifier sauf que, bien sûr, <=> nécessite deux paramètres génériques, pas un. C'est ridicule, moi!)

    Si vous créez plutôt une autre classe implémentant <=>, transmettez une instance de cette classe au constructeur.
  3. Oui, selon les <=> Javadocs .

Modifier: La relecture de la question n'a aucun sens. Si vous avez déjà une liste, il est judicieux de mettre en œuvre <=> puis d'appeler <=> dessus. Aucune carte n'est nécessaire.

Un petit code:

public class MyObject implements Comparable<MyObject> {
    // ... your existing code here ...
    @Override
    public int compareTo(MyObject other) {
        // do smart things here
    }
}

// Elsewhere:
List<MyObject> list = ...;
Collections.sort(list);

Comme avec le <=>, vous pouvez créer un <=> et le transmettre à <=> .

Autres conseils

1.

Cela dépend de la situation. Disons que l'objet A doit trier avant l'objet B dans votre ensemble. S'il est généralement logique de considérer A comme inférieur à B, la mise en œuvre de Comparable aurait alors du sens. Si l'ordre n'a de sens que dans le contexte dans lequel vous utilisez l'ensemble, vous devriez probablement créer un comparateur.

2.

new TreeMap(new MyComparator());

Ou sans créer de classe MyComparator:

new TreeMap(new Comparator<MyClass>() {
    int compare(MyClass o1, MyClass o2) { ... }
});

3. Oui.

Puisque vous avez une liste et obtenez une erreur parce que vous avez un argument sur la carte, je suppose que vous voulez un ensemble trié:

SortedSet<Ktr> set = new TreeSet<Ktr>(comparator);

Ceci gardera l'ensemble trié, c'est-à-dire qu'un itérateur retournera les éléments dans leur ordre de tri. Il existe également des méthodes spécifiques à SortedSet , qui vous voudrez peut-être utiliser. Si vous souhaitez également revenir en arrière, vous pouvez utiliser NavigableSet .

Ma réponse suppose que vous utilisez la TreeMap mise en œuvre de SortedMap.

1.) Si vous utilisez Comparable, vous avez le choix. Vous pouvez implémenter Comparator directement sur votre classe ou transmettre un <=> séparé au constructeur.

2.) Exemple:

Comparator<A> cmp = new MyComparator();
Map<A,B> map = new TreeMap<A,B>(myComparator);

3.) Oui c'est vrai. En interne, TreeMap utilise un arbre rouge-noir stocker les éléments dans l'ordre d'insertion; le temps nécessaire pour effectuer une insertion (ou une extraction) est O (journal N).

Vous faites un Comparator<ClassYouWantToSort>. Ensuite, le comparateur compare le champ sur lequel vous souhaitez trier.

Lorsque vous créez le TreeMap, vous créez un TreeMap<ClassYouWantToSort> et vous transmettez le Comparator en tant qu'argument. Ensuite, lorsque vous insérez des objets de type ClassYouWantToSort, le Comparable utilise votre Comparables pour les trier correctement.

EDIT: Comme le note Adamski, vous pouvez également créer Map lui-même TreeSet. L’avantage est que vous avez moins de classes à traiter, le code est plus simple et <=> une commande par défaut pratique. L'inconvénient est que <=> peut ne pas avoir un seul ordre évident, vous devrez donc implémenter <=> pour d'autres situations de toute façon. Vous risquez également de ne pas pouvoir changer <=>.

EDIT2: Si vous ne jetez que dans une collection d'objets et que ce n'est pas un <=> (c.-à-d. que ce n'est pas un mappage d'un ensemble d'objets à un autre), vous voulez un <=> , pas un <=>.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top