Алфавитная сортировка коллекции Java на основе значения toString ее элементов-членов - PullRequest
25 голосов
/ 17 февраля 2009

Предположим, у меня есть пользовательский класс Java с именем Foo, например:

public class Foo 
{

    private String aField;

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

}

И коллекция, такая как:

List<Foo> aList;

Я хочу отсортировать Список по алфавиту на основе возвращенного значения каждого члена .toString ().

Я пытался использовать метод Collections.sort (), но в результате получилось не то, что я пытался. Что мне нужно сделать, чтобы сделать это?

Ответы [ 9 ]

66 голосов
/ 17 февраля 2009
Collections.sort(fooList,
                 new Comparator<Foo>()
                 {
                     public int compare(Foo f1, Foo f2)
                     {
                         return f1.toString().compareTo(f2.toString());
                     }        
                 });

Предполагается, что toString никогда не возвращает ноль и что в списке нет нулевых элементов.

18 голосов
/ 17 февраля 2009

Используйте API sort(List list, Comparator c), который определяет компаратор, и реализуйте его так, как вы хотите.

В качестве альтернативы, если вам конкретно не нужен список, используйте SortedSet, то же самое касается компаратора.

16 голосов
/ 07 сентября 2009

google-collection делает это действительно легко с Ordering :

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

Стоит ли использовать целую стороннюю библиотеку только для того, чтобы использовать что-то, что вы могли бы написать тривиально, используя Comparator (как и другие), стоит? Нет, но google-collection так хорош, что вы захотите его получить по ряду других причин.

На фронте сортировки вы также можете легко выполнять такие действия, как реверсирование:

Ordering.usingToString().reverse();

или разрыв связи:

Ordering.usingToString().compound(someOtherComparator);

или иметь дело с нулями:

Ordering.usingToString().nullsFirst();

и т. Д., Но там есть куча других вещей (не только связанных с сортировкой, конечно), которые приводят к действительно выразительному коду. Проверьте это!

7 голосов
/ 17 февраля 2009
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();
    }

}

, а затем

Collections.sort (список);

5 голосов
/ 07 декабря 2016

Версия Java 8:

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

Или потоковое:

List<Foo> sortedList = unsortedList
    .stream()
    .sorted(Comparator.comparing(Object::toString)))
    .collect(Collectors.toList());
5 голосов
/ 17 февраля 2009

Я бы сделал что-то очень похожее на Пьера:

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

Тогда, как и Пьер, я бы использовал Collections.sort(list), как предполагает Пьер.

3 голосов
/ 06 сентября 2009

lambdaj позволяет сортировать, фильтровать и вообще манипулировать коллекциями без написания циклов или скрытых внутренних классов. Например, запрашиваемая вами сортировка может быть выполнена следующим образом:

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

Если вы заинтересованы в этом, проверьте его по адресу:

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

3 голосов
/ 17 февраля 2009

Я бы настоятельно рекомендовал вам использовать toString только для целей отладки ... однако ... чтобы расширить то, что Ювал А написал выше ...

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

Однако вы действительно должны иметь Foo для реализации Comarable или написать надлежащий Compartor, который не использует toString.

1 голос
/ 17 февраля 2009

Если вы хотите, чтобы коллекция оставалась отсортированной, а не сортируемой в определенных точках, вы можете поместить ее в TreeSet с определенным компаратором. В противном случае я бы использовал метод Collections.sort, уже упомянутый Yuval.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...