web-dev-qa-db-fra.com

Comment utiliser l'interface de comparaison

Je suis nouveau sur Java et je ne comprends pas vraiment comment utiliser l'interface de comparateur . J'ai un ArrayList de Items dans une classe Inventory et une classe Item . Dans la classe Item, j'ai écrit:

public class Item implements Comparator<Item> {
    //stuff
    ...
    @Override
    public int compare(Item a, Item b) {
        if (a.getID().compareToIgnoreCase(b.getID())>0)
            return 1;
        else if (a.getID().compareToIgnoreCase(b.getID())<0)
            return -1;
        else
            return 0;
    }
}

La méthode getID () donne simplement l'identifiant, que je dois utiliser pour classer par ordre alphabétique les éléments . Je ne sais pas si c'est vrai, cela m'a fait mettre l'annotation @Override, je ne sais pas pourquoi. Aussi, j'ai écrit une interface qui dit juste:

 public interface Comparator<Item>
{
    int compare(Item a, Item b);
}

Je ne suis pas sûr de ce bit. De plus, comment implémenter cette méthode pour trier l'arraylist créé dans la classe d'inventaire?

Merci, si ma question n'a pas de sens ou nécessite des éclaircissements, faites le moi savoir.

12
bassandguitar

Pour utiliser l'interface Comparator , vous devez l'implémenter et la transmettre en tant que classe anonyme à Collections.sort (List list, Comparator c) } en tant que second paramètre.

Si vous souhaitez ne transmettre que la liste à Collections.sort (Liste de listes) }, votre classe Item a alors pour implémenter l'interface Comparable .

Donc, dans les deux cas, les méthodes Collections.sort savent ordonner les éléments de votre liste

voici un exemple de code:

Classe d'objets implémentant Comparable + Inventaire contenant une liste d'éléments

public class Item implements Comparable<Item> {

    String id = null;

    public Item(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return id;
    }

    @Override
    public int compareTo(Item o) {
        return - id.compareToIgnoreCase(o.id);
    }
}


public class Inventory {

    List<Item> items = new ArrayList<>();

    public void addItem(Item item) {
        items.add(item);
    }

    public static void main(String[] args) {
        Inventory inventory = new Inventory();
        inventory.addItem(new Item("2"));
        inventory.addItem(new Item("4"));
        inventory.addItem(new Item("1"));
        inventory.addItem(new Item("7"));

        Collections.sort(inventory.items, new Comparator<Item>() {
            @Override
            public int compare(Item o1, Item o2) {
                return o1.id.compareToIgnoreCase(o2.id);
            }
        });
        System.out.println(inventory.items);

        Collections.sort(inventory.items);
        System.out.println(inventory.items);

    }
}

Sortie

[1, 2, 4, 7] // ascending
[7, 4, 2, 1] // descending since the compareTo method inverts the sign of the comparison result.
11
A4L

EDIT: Tout d’abord, quelques éléments:

  1. L'annotation @Override ne devrait pas être obligatoire. Si Eclipse veut que vous le mettiez, ne vous inquiétez pas.
  2. N'écrivez pas votre propre interface de comparateur. Supprimez cette définition NAO et utilisez celle fournie par Java. Réinventer la roue viole probablement le code de langage non programmé de 15 façons différentes. Utilisez import Java.util.Comparator; tout en haut de votre code (avant le public class) pour a) utiliser la version fournie par Java et b) rendre votre code compatible avec à peu près tout ce qui existe dans le monde.

L'interface de comparateur n'est pas utilisée pour créer une classe pouvant se mettre en ordre. C'est l'interface comparable.

Les deux sont similaires, je vais donc les décrire ici.

Java.util.Comparator

Comme vous le savez déjà, l’interface Comparator a une méthode: compare. Le comparateur est générique (utilise les crochets <>) et prend le type qu'il comparera à l'intérieur du <>. Le fait est que les comparateurs sont utilisés pour comparer les éléments de autres classes. Par exemple, je pourrais créer un comparateur pour Java.lang.Integers qui retourne le contraire de "l'ordre naturel" (comment les entiers sont habituellement commandés).

Les comparateurs servent principalement à donner aux autres objets un moyen de trier leurs paramètres s’ils ne sont pas dans l’ordre naturel. Par exemple, la classe Java.util.TreeSet prend un comparateur pour sa capacité de tri.

Java.lang.Comparable

Le but de Comparable est de dire qu'un objet peut être comparé. Il est également générique et prend le type auquel il peut être comparé. Par exemple, un Comparable<String> peut être comparé à Strings.

Comparable a une méthode: compareTo(). Contrairement à la fonction compare() du comparateur, compareTo prend un paramètre. Cela fonctionne comme compare, sauf qu'il utilise l'objet invoquant comme un paramètre. Donc, comparableA.compareTo(comparableB) est identique à comparator.compare(comparableA, comparableB).

Comparable établit principalement l'ordre naturel des objets et constitue le moyen par défaut de comparer des objets. Le rôle du comparateur est de remplacer cet ordre naturel lorsque l'on a des besoins différents en matière de comparaison ou de tri des données.

Tri de la liste de tableaux

Pour trier une List, vous pouvez utiliser la méthode déjà disponible: faites défiler jusqu'à sort dans le Java.util.Collections classe . Une méthode prend un comparateur, l'autre pas. sort est statique; utilisez Collections.sort(...), pas Collections c = new Collections(); c.sort(...). (Collections n'a même pas de constructeur, alors meh.)

16
ameed

Vous mélangez les interfaces Comparator et Comparable.

Comparateur: http://docs.Oracle.com/javase/6/docs/api/Java/util/Comparator.html

Comparable: http://docs.Oracle.com/javase/6/docs/api/Java/lang/Comparable.html

Le rôle de Comparator est une classe (déclarée anonymement sur place ou autrement) pouvant être transférée à une opération nécessitant un ordre et définissant le tri qui sera utilisé sur l'article. Comparator doit être utilisé à l'extérieur de la classe qui doit être triée, s'il existe une autre méthode de tri.

Le but de Comparable est de dire que la classe (qui implémente Comparable) a un ordre naturel - et c'est ce qu'elle est. Si votre classe nécessitant un tri a un ordre naturel, définissez-le comme étant Comparable. (Une classe qui implémente l'ordre de tri de Comparable peut toujours être remplacée par un comparateur. Par contre, si la classe n'est pas comparable, il est également obligatoire de passer un comparateur pour que la commande soit possible.)

3
Patashu

Vous avez implémenté la mauvaise interface, vous voulez Comparable

0
Hiro2k

L'utilisation de @Override annotation est une pratique courante dans les éditeurs comme Eclipse, netbeans pour informer le développeur qu'il substitue/implémente une méthode classe/interface parent. C'est optionnel. 

N'implémentez pas cette interface dans votre classe Item. Créez une classe new et implémentez l'interface Comparator

public class ItemCompare implements Comparator<Item> {

    @Override
    public int compare(Item a, Item b) {
        if (a.getID().compareToIgnoreCase(b.getID())>0)
            return 1;
        else if (a.getID().compareToIgnoreCase(b.getID())<0)
            return -1;
        return 0;
    }
} 

Et ensuite, dans votre classe principale, faites ceci:

ArrayList al = new ArrayList<Item>

Collections.sort(al, new ItemCompare())
0
Ravi Trivedi