Trier par ordre alphabétique une Collection Java en fonction de la valeur' toString ' de ses éléments membres

Supposons que J'ai une classe Java définie par L'utilisateur appelée Foo telle que:

public class Foo 
{

    private String aField;

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

}

Et une Collection telle que:

List<Foo> aList;

Ce que je cherche à faire est de trier la liste Par Ordre alphabétique en fonction de chaque membre retourné '.ToString () ' valeur.

J'ai essayé d'utiliser les Collections.méthode sort (), mais le résultat n'était pas ce que j'essayais. Que dois-je faire pour accomplir cela?

22
demandé sur Tom Neyland 2009-02-17 01:06:56

9 réponses

Utilisez L'API sort(List list, Comparator c) qui spécifie un comparateur, et implémentez est comme vous le souhaitez.

Sinon, si vous n'avez pas spécifiquement besoin D'une liste, utilisez un SortedSet, il en va de même avec le comparateur.

18
répondu Yuval Adam 2009-02-16 22:09:03
Collections.sort(fooList,
                 new Comparator<Foo>()
                 {
                     public int compare(Foo f1, Foo f2)
                     {
                         return f1.toString().compareTo(f2.toString());
                     }        
                 });

En supposant que toString ne renvoie jamais null et qu'il n'y a pas d'éléments null dans la liste.

62
répondu Dan Dyer 2009-02-16 22:15:32

Google-collections fait vraiment facilement avec la Commande:

Collections.sort(list, Ordering.usingToString());

Est-ce que l'introduction d'une bibliothèque 3rd entière juste pour utiliser quelque chose que vous pourriez écrire trivialement en utilisant un comparateur (comme d'autres l'ont fourni) en vaut la peine? Non, mais Google-collections est tellement cool que vous voudrez l'avoir de toute façon pour un tas d'autres raisons.

Sur le front de tri, vous pouvez également facilement faire des choses comme inverser:

Ordering.usingToString().reverse();

Ou briser les liens:

Ordering.usingToString().compound(someOtherComparator);

Ou traiter avec les valeurs null:

Ordering.usingToString().nullsFirst();

Etc., mais il y a beaucoup plus de choses là-dedans (pas seulement liées au tri, bien sûr) qui conduit à un code vraiment expressif. Check it out!

15
répondu Cowan 2009-09-07 00:20:28
public class Foo
   implements Comparable<Foo>
{

    private String aField;

    public Foo(String s)
       {
       aField=s;
        }


    public String getAField()
        {
        return aField;
        }

   public int compareTo(Foo other)
        {
        return getAField().compareTo(other.getAField());
        }


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

}

, puis

Collections.trier (liste);

7
répondu Pierre 2009-02-16 22:14:22

Je ferais quelque chose de très similaire à Pierre:

public class Foo implements Comparable<Foo>
{
    private String aField;

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

    public int compareTo(Foo o)
    {
        return this.toString().compareTo(o.toString());
    }
}

Ensuite, comme Pierre, j'utiliserais Collections.sort(list) Comme Pierre le suggère.

5
répondu psykotedy 2012-08-21 14:31:07

Je vous conseille fortement d'utiliser uniquement toString à des fins de débogage... cependant... pour développer ce que Yuval a écrit ci-dessus...

public class X
    implements Comparator
{
    public int compare(final Foo a, final Foo b) 
    {
        return (a.toString().compareTo(b.toString()));
    }
}

Cependant, vous devriez vraiment avoir Foo implémenter Comarable ou écrire un Comparteur approprié qui n'utilise pas toString.

3
répondu TofuBeer 2009-02-16 22:36:23

Lambdaj vous permet de trier, filtrer et en général manipuler des collections sans écrire de boucles ou de classes internes obscures. Par exemple, le tri que vous demandiez peut être réalisé comme suit:

sort(foos, on(Foo.class).toString());

Si cela vous intéresse, consultez-le à:

Http://code.google.com/p/lambdaj/

3
répondu Mario Fusco 2009-09-06 15:07:25

La version Java 8:

list.sort(Comparator.comparing(Object::toString));

Ou streaming:

List<Foo> sortedList = unsortedList
    .stream()
    .sorted(Comparator.comparing(Object::toString)))
    .collect(Collectors.toList());
3
répondu David Leppik 2016-12-07 16:12:48

Si vous voulez que la collection reste triée, plutôt que de la Trier à des points spécifiques, vous pouvez la placer dans un TreeSet avec un comparateur défini. Sinon, j'utiliserais les Collections.méthode de tri déjà mentionnée par Yuval.

1
répondu Paul Tomblin 2009-02-16 22:13:09