2011-04-27 3 views
1

Je possède ArrayList d'objets personnalisés. J'ai besoin d'implémenter le tri par différents paramètres, c'est-à-dire l'année et le prix croissant et décroissant. Quelle est la meilleure façon de le faire? J'ai pensé à mettre en œuvre Comparator et passer le mode de tri au constructeur lors de l'instanciation du comparateur. Est-ce une bonne idée?Java comparant des objets personnalisés

Répondre

2

Je suggère d'utiliser une implémentation différente pour Comparator par type de tri. Les classes internes anonymes, enums et, dans Java SE 8 (!), Lambdas, sont de bons moyens pour implémenter Comparator et d'autres objets de type fonction sans état.

Vous pouvez inverser avec Collections.reverseOrder.

2

Oui. Une coutume Comparator est un très bon moyen de le faire.

Comme mentionné par @Tom et @ Puce, vous pouvez reverse the order de votre Comparator à la volée.

+2

Un 'Comparator' personnalisé par type de tri, mais inversé avec' Collections.reverseOrder': http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#reverseOrder(java .util.Comparator) –

0

La réponse canonique est d'implémenter deux comparateurs - un qui trie dans l'ordre croissant, et un en descendant.

+3

Utiliser Collections.reverseOrder – Puce

+0

@Puce - bon point. – CPerkins

2

C'est une façon. Mais, cela n'a vraiment de sens que si c'est un moyen par défaut. Considérez la classe Customer suivante. Généralement, vous triez toujours les clients par leur nom. Mais parfois, vous voulez les trier par leur limite de crédit.

Il est logique d'implémenter Comparable pour plus de commodité. À tout le moins, vous pouvez rendre les comparateurs publics des composants finaux de la classe pour que les utilisateurs y aient facilement accès, et vous pouvez avoir confiance qu'ils ont été écrits par l'auteur de la classe (ou au moins quelqu'un connaissant bien la classe).

class Customer implements Comparable<Customer> { 

    public final Comparator<Customer> byCreditLimit = new Comparator<Customer>() { 
     public int compare(Customer c1, Customer c2) { 
      return c1.creditLimit.compareTo(c2.creditLimit); 
     } 
     public boolean equals(Object o) { 
      return o == this; 
     } 
    } 

    private String name; 
    private BigDecimal creditLimit; 

    public Customer(String name, BigDecimal creditLimit) { 
     this.name = name; 
     this.creditLimit = creditLimit; 
    } 

    public boolean equals(Object o) { 
     if(o instanceof Customer) { 
      Customer c = Customer(o); 
      return name.equals(c.name); 
     } 
     return false; 
    } 

    public int hashCode() { 
     return name.hashCode(); 
    } 

    public int compareTo(Customer c) { 
     return name.compareTo(c.name); 
    } 
} 
+0

Pourriez-vous dire pourquoi Comparable est meilleur que Comparator? –

+2

Principalement pour la commodité. C'est une façon de dire: «La plupart du temps, vous devez trier les objets de ce type. C'est juste une chose de moins à penser. Imaginez que vous êtes un développeur utilisant une classe. Vous voulez que les objets soient triés pour des temps de recherche plus rapides. Le développeur sait que vous devriez obtenir une distribution relativement bonne en triant le nom, alors que le tri par limite de crédit serait moins efficace (beaucoup peuvent avoir le même crédit, mais l'égal indique qu'un ensemble aura au plus un avec un prénom). En utilisant Comparable, l'auteur peut fournir un mécanisme de comparaison par défaut. – corsiKa

+1

Si une classe implémente Comparable, elle indique qu'elle a un "ordre naturel". De bons échantillons sont par exemple les classes de nombre (Integer, Long), qui sont triées par le nombre enveloppé. S'il n'y a pas de «commande naturelle» ou si vous voulez quelque chose de différent de la «commande naturelle» -> utilisez un comparateur – Puce

Questions connexes