Подтвердить что ты не робот

По алфавиту Сортировка коллекции Java, основанная на значении 'toString' его элементов-членов

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

public class Foo 
{

    private String aField;

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

}

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

List<Foo> aList;

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

google-collections делает это очень легко с Ordering:

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

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

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

Ordering.usingToString().reverse();

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

Ordering.usingToString().compound(someOtherComparator);

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

Ordering.usingToString().nullsFirst();

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

Ответ 4

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

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

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), как предлагает Пьер.

Ответ 6

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

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

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

Ответ 7

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

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

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

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

Ответ 8

Версия Java 8:

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

Или потоковая передача:

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

Ответ 9

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