web-dev-qa-db-ja.com

メンバー項目の「toString」値に基づいてJavaコレクションをアルファベット順にソートします

次のようなユーザー定義のJava Fooというクラスがあるとします:

public class Foo 
{

    private String aField;

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

}

そして、次のようなコレクション:

List<Foo> aList;

私がやろうとしているのは、各メンバーの返された「.toString()」値に基づいてリストをアルファベット順にソートすることです。

Collections.sort()メソッドを使用してみましたが、結果は意図したものではありませんでした。これを達成するために何をする必要がありますか?

25
Tom Neyland

コンパレータを指定するAPI sort(List list, Comparator c)を使用し、実装は希望どおりです。

別の方法として、リストが特に必要ない場合は、 SortedSet を使用します。これはコンパレータにも当てはまります。

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

ToStringが決してnullを返さず、リストにnullアイテムがないと仮定します。

67
Dan Dyer

google-collections は、これを本当に簡単にします Ordering

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

Comparator(他の人が提供している)を使って簡単に書くことができるものを使用するためだけに、サードパーティライブラリ全体を導入する価値はありますか?いいえ、しかしgoogle-collectionsはとてもクールなので、他の多くの理由からとにかくそれを持ちたいと思うでしょう。

並べ替えの面では、反転などのことも簡単に行えます。

Ordering.usingToString().reverse();

またはタイを破る:

Ordering.usingToString().compound(someOtherComparator);

またはヌルを扱う:

Ordering.usingToString().nullsFirst();

などがありますが、実際には表現力豊かなコードにつながるものがたくさんあります(もちろん、並べ替え関連だけでなく)。見てみな!

16
Cowan
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(list);

7
Pierre

Java 8バージョン:

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

またはストリーミング:

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

私はピエールに非常に似たようなことをします:

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

次に、Pierreのように、Collections.sort(list)をPierreが提案するように使用します。

5
psykotedy

lambdajを使用すると、ループを作成したり、内部クラスを不明瞭にしたりすることなく、コレクションをソート、フィルタリング、および一般的に操作できます。たとえば、次のようにして、求めていたソートを実現できます。

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

興味のある方は、以下をご覧ください。

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

3
Mario Fusco

デバッグの目的でのみtoStringを使用することを強くお勧めします...ただし、上記のYuval Aの記述を拡張するには...

 publicクラスX 
はComparator 
 {
 public int compare(final Foo a、final Foo b)
 {
 returnを実装します(a.toString()。compareTo(b.toString())); 
} 
} 

ただし、FooでComarableを実装するか、toStringを使用しない適切なCompartorを作成する必要があります。

3
TofuBeer

コレクションを特定のポイントで並べ替えるのではなく、並べ替えたままにする場合は、定義済みのコンパレータを使用してTreeSetにコレクションを配置できます。それ以外の場合は、Yuvalで既に説明したCollections.sortメソッドを使用します。

1
Paul Tomblin