按字母顺序基于其成员项的“toString”值对Java Collection进行排序

时间:2009-02-16 22:06:56

标签: java sorting collections

假设我有一个名为Foo的用户定义的Java类,例如:

public class Foo 
{

    private String aField;

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

}

收集如:

List<Foo> aList;

我要做的是根据每个成员返回的'.toString()'值按字母顺序对列表进行排序。

我尝试过使用Collections.sort()方法,但结果不是我尝试的。 为了做到这一点,我需要做什么?

10 个答案:

答案 0 :(得分:66)

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

假设toString永远不会返回null,并且列表中没有空项。

答案 1 :(得分:18)

使用指定比较器的API sort(List list, Comparator c),并按照您的意愿实现。

或者,如果您不需要特定列表,请使用SortedSet,与比较器相同。

答案 2 :(得分:16)

google-collections使Ordering

变得非常简单
Collections.sort(list, Ordering.usingToString());

引入一个完整的第三方库只是为了使用一些你可以使用Comparator(正如其他人提供的那样)写得很有价值的东西值得吗?不,但谷歌收藏品非常酷,无论如何都会因为其他原因而无法使用它。

在排序方面,您还可以轻松完成倒车等事情:

Ordering.usingToString().reverse();

或打破关系:

Ordering.usingToString().compound(someOtherComparator);

或处理空值:

Ordering.usingToString().nullsFirst();
等等,但是那里有更多的东西(当然不仅仅是排序相关的),这导致了真正富有表现力的代码。看看吧!

答案 3 :(得分:7)

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(列表);

答案 4 :(得分: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)

答案 5 :(得分:5)

Java 8版本:

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

或流媒体:

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

答案 6 :(得分:3)

我强烈建议你只使用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或编写一个不使用toString的正确的Compartor。

答案 7 :(得分:3)

lambdaj允许您排序,过滤和一般操作集合,而无需编写循环或模糊内部类。例如,您要求的排序可以如下实现:

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

如果您对此感兴趣,请查看:

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

答案 8 :(得分:1)

如果您希望对集合保持排序,而不是在特定点对其进行排序,则可以将其放在具有已定义的Comparator的TreeSet中。否则,我将使用Yuval已经提到的Collections.sort方法。

答案 9 :(得分:0)

按POJO int属性(升序或降序)排序ArrayList:

Collections.sort(myPojoList, (a, b) -> a.getId() - b.getId()); //ASC
Collections.sort(myPojoList, (a, b) -> b.getId() - a.getId()); //DESC

//Alternatively use Integer.compare()
Collections.sort(myPojoList, (a, b) -> Integer.compare(a.getId(), b.getId())); //ASC
Collections.sort(myPojoList, (a, b) -> Integer.compare(b.getId(), a.getId())); //DESC

在POJO String属性上排序ArrayList:

Collections.sort(myPojoList, (a, b) -> a.getName().compareTo(b.getName())); //ASC
Collections.sort(myPojoList, (a, b) -> b.getName().compareTo(a.getName())); //DESC

在POJO布尔属性上排序ArrayList:

Collections.sort(myPojoList, (a, b) -> Boolean.compare(a.isMale(), b.isMale())); //ASC
Collections.sort(myPojoList, (a, b) -> Boolean.compare(b.isMale(), a.isMale())); //DESC

额外:获取不同的ArrayList

myPojoList= new ArrayList<>(new LinkedHashSet<>(myPojoList)); //Distinct