2009-02-16 17 views
20

Supongamos que tengo una clase Java definido por el usuario llamado Foo tales como:alfabéticamente ordenar una colección de Java en base al valor 'toString' de sus productos Miembro

public class Foo 
{ 

    private String aField; 

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

} 

y una colección tales como:

List<Foo> aList; 

Lo que quiero hacer es ordenar la lista alfabéticamente según el valor '.toString()' devuelto por cada miembro.

He intentado utilizar el método Collections.sort(), pero el resultado no fue el que estaba intentando. ¿Qué debo hacer para lograr esto?

Respuesta

17

Use la API sort(List list, Comparator c) que especifica un comparador, y impleméntelo como desee.

Alternativamente, si no necesita específicamente una lista, utilice un SortedSet, lo mismo ocurre con el comparador.

1

Si desea que la colección permanezca ordenada, en lugar de ordenarla en puntos específicos, puede colocarla en un TreeSet con un comparador definido. De lo contrario, utilizaría el método Collections.sort ya mencionado por Yuval.

+0

ya editado mi mensaje mencionar SortedSet;) –

6
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(); 
    } 

} 

y luego

Collections.sort (lista);

58
Collections.sort(fooList, 
       new Comparator<Foo>() 
       { 
        public int compare(Foo f1, Foo f2) 
        { 
         return f1.toString().compareTo(f2.toString()); 
        }   
       }); 

Suponiendo que toString nunca devuelve nulo y que no hay elementos nulos en la lista.

+0

Específicamente escribir este comparador puede ser innecesario, ya que el autor de la pregunta simplemente quiere comparar dos objetos por toString. Me parece que el tipo puede ser innecesario. –

+0

@ Nathan. Sí, el tipo genérico no necesita ser más específico que Object. No tiene que definir el comparador en línea como lo hice tampoco. –

+0

Lo que es aún mejor en Java 8 con una lambda. –

3

Yo aconsejaría encarecidamente que use only toString para fines de depuración ... sin embargo ... ampliar lo Yuval Un escribió más arriba ...

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

Sin embargo, usted realmente debe tener Foo implementar o Comarable escriba un Compartidor adecuado que no haga uso de toString.

5

me gustaría hacer algo muy similar a 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()); 
    } 
} 

Entonces, al igual que Pedro, me gustaría utilizar Collections.sort(list) como sugiere Pierre.

2

lambdaj le permite ordenar, filtrar y en general manipular colecciones sin escribir bucles u oscurecer las clases internas. Por ejemplo, la clasificación se puede lograr, ya que sigue usted preguntaba:

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

Si usted está interesado en él echarle un vistazo en:

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

+0

Impresionante, nunca había oído hablar de lambdaj, pero puedo ver de inmediato lo útil que puede ser. –

+0

Hola, quería hacerte saber que estoy usando lambdaj en un nuevo proyecto y está funcionando muy bien. Gracias de nuevo. –

+0

Si es un usuario feliz de lambdaj podría ser genial si agrega aquí sus impresiones . Gracias :) http://code.google.com/p/lambdaj/wiki/WhoIsUsingLambdaj –

14

google-collections lo hace muy fácil con Ordering:

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

Está trayendo una biblioteca completa de terceros solo para usar algo que podría escribir trivialmente usando un Compara tor (como otros han proporcionado) vale la pena? No, pero google-collections es tan genial que querrás tenerlo de todos modos por muchas otras razones.

En el frente de la clasificación, también se puede hacer fácilmente cosas como que retrocede:

Ordering.usingToString().reverse(); 

o romper los lazos:

Ordering.usingToString().compound(someOtherComparator); 

o lidiar con nulos:

Ordering.usingToString().nullsFirst(); 

etc. , pero hay muchas otras cosas (no solo relacionadas con la clasificación, por supuesto) que conducen a un código realmente expresivo. ¡Echale un vistazo!

2

La versión de Java 8:

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

o streaming:

List<Foo> sortedList = unsortedList 
    .stream() 
    .sorted(Comparator.comparing(Object::toString))) 
    .collect(Collectors.toList()); 
Cuestiones relacionadas