36

以下は、ArrayList の簡単な並べ替えプログラムです。

ArrayList<String> list = new ArrayList<String>();

list.add("1_Update");
list.add("11_Add");
list.add("12_Delete");
list.add("2_Create");

Collections.sort(list);
for (String str : list) {
  System.out.println(str.toString());
}

このプログラムの出力は次のようになると予想していました。

1_Update
2_Create
11_Add
12_Delete

しかし、このプログラムを実行すると、次のような出力が得られます。

11_Add
12_Delete
1_Update
2_Create

これはなぜですか? また、予想される出力に示されているように ArrayList を並べ替えるにはどうすればよいですか?

4

12 に答える 12

70

カスタムコンパレータを書くことができます:

Collections.sort(list, new Comparator<String>() {
    public int compare(String a, String b) {
        return Integer.signum(fixString(a) - fixString(b));
    }
    private int fixString(String in) {
        return Integer.parseInt(in.substring(0, in.indexOf('_')));
    }
});
于 2009-05-20T21:57:07.227 に答える
8

このタイプのデータを文字列として並べ替えると、数字を含む文字自体が比較されます。たとえば、「1」で始まる文字列はすべて一緒になります。したがって、注文はこれに似ています...

1 10 100 2 20 200

文字列の先頭にある可変長の数値など、文字列のサブセットに意味を割り当てていることをソートが「認識」することは決してありません。数値を文字列として並べ替える場合、最大の数値をカバーするために必要なだけ左にゼロをパディングすることは役立ちますが、例のようにデータを制御しない場合、実際には問題は解決しません。その場合、種類は...

001 002 010 020 100 200

于 2009-05-20T21:14:16.207 に答える
6

数字ではなく、テキスト (アルファベット順) として並べ替えられます。これを回避するには、nsayer の回答で提案されているように、カスタム コンパレータを実装できます。

于 2009-05-20T21:10:27.790 に答える
3

辞書式比較を行っています。それらをソートする各文字列の最初の文字を比較します。次に、最初の文字が同じ文字列の 2 番目の文字列を比較します。「_」文字を数値と比較すると、8 > 7 および a > 9 のように、単一の数字よりも値が大きくなります。数値比較ではなく、文字比較を行っていることに注意してください。

スクリプト名の名前を変更するよりも優れた、独自のカスタム ソート ルーティングを実装する方法があります。

スクリプト名の変更がオプションである場合、これにより他のスクリプト ツールを使用できるようになります。1つのフォーマットは

01_create_table.sql
02_create_index.sql
11_assign_privileges.sql

最初の 2 桁を 2 文字に保つことで、辞書式比較が機能します。

于 2009-05-20T21:19:42.887 に答える
2

Collections.sort() メソッドのドキュメントには次のように書かれています。

要素の自然順序付けに従って、指定されたリストを昇順に並べ替えます。

これは、文字列の場合、リストをアルファベット順に取得することを意味します。文字列 11_assign_privileges.sql は文字列 1_create_table.sql の前に来て、12_07_insert_static_data.sql は 1_create_table.sql の前に来ます。したがって、プログラムは期待どおりに動作しています。

于 2009-05-20T21:13:33.353 に答える
0

IComparable インターフェイスを追加して、特定のプロパティで並べ替えることができます。たとえば、ストアのアイテムのコレクションがある場合、それらを価格またはカテゴリなどで並べ替えたい場合があります。名前で注文したい場合は、次の例をご覧ください。

ArrayList がアイテムの name プロパティによってどのようにソートされるかに注目してください。IComparable を追加しないと、sort メソッドを使用するとエラーがスローされます。

ここに画像の説明を入力

static void Main(string[] args)
    {
        ArrayList items = new ArrayList();
        items.Add(new Item("book", 12.32));
        items.Add(new Item("cd", 16.32));
        items.Add(new Item("bed", 124.2));
        items.Add(new Item("TV", 12.32));

        items.Sort();

        foreach (Item temp in items)
            Console.WriteLine("Name:{0} Price:{1}", temp.name, temp.price);
        Console.Read();            
    }


    class Item: IComparable
    {
        public string name;
        public double price;

        public Item(string _name, double _price)
        {
            this.name = _name;
            this.price = _price;
        }

        public int CompareTo(object obj)
        {   
            //note that I use the name property I may use a different one
            int temp = this.name.CompareTo(((Item)obj).name);
            return temp;
        }
    }
于 2011-03-12T19:01:53.643 に答える
0

Collection.sort() を任意に並べ替えるには、使用できます

Collections.sort(List list, Comparator c)  

次に、文字列を分割し、最初に数値に基づいてソートし、次に残りに基づいてソートする Comparator を実装するだけです。

于 2009-05-20T21:36:14.553 に答える
0

文字列はアルファベット順にソートされ、アンダースコア文字は数字の文字の後にあるためです。目的の結果を得るには、「自然順序」を実装するコンパレータを提供する必要があります。

于 2009-05-20T21:13:43.553 に答える
0

文字列比較アルゴリズムは、一度に各文字を比較します。1前に並べ2ます。1後に aまたは aが続くことは重要ではありません2

100の前に並べ替えます2。この動作が望ましくない場合は、このケースを処理する比較アルゴリズムが必要です。

于 2009-05-20T21:15:28.230 に答える
0

他の人が述べているように、要素はデフォルトでアルファベット順にソートされます。解決策は、具体的な java.util.Comparator クラスを定義し、それを sort メソッドの 2 番目の引数として渡すことです。コンパレータは、文字列から先頭の整数を解析して比較する必要があります。

于 2009-05-20T21:17:40.240 に答える
0

説明は、文字列が文字列としてソートされていることであると誰もがすでに指摘しており、数値はすでに自然順序の文字列比較に注意を向けています。そのコンパレーターを自分で作成することは素晴らしい演習であり、テスト駆動開発を実践する絶好の機会であることを付け加えておきます。Code Camp で TDD のデモンストレーションに使用しました。スライドとコードはこちら.

于 2009-05-20T21:42:04.620 に答える
0

上記のように、自然な並べ替えを実装する Comparator の実装を探しています。Jeff Atwood は、自然な並べ替えに関する優れた記事を以前に書きました。一読の価値があります。

Java 実装を探しているなら、これが役に立つと思います: http://www.davekoelle.com/alphanum.html

于 2009-05-20T21:42:30.330 に答える