Frage

Hier ist ein einfaches Sortierprogramm einer 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());
}

Ich habe erwartet, die Ausgabe dieses Programms:

1_Update
2_Create
11_Add
12_Delete

Aber wenn ich laufe dieses Programm, das ich ausgegeben bin immer wie:

11_Add
12_Delete
1_Update
2_Create

Warum ist das und wie bekomme ich die Arraylist, wie in der erwarteten Ausgabe gezeigt zu sortieren?

War es hilfreich?

Lösung

Sie können einen benutzerdefinierten Komparator schreiben:

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

Andere Tipps

Wenn Sie diese Art von Daten als String sortieren, es vergleicht die Zeichen selbst, einschließlich der Ziffern. Alle von der Zeichenfolge, die mit „1“, zum Beispiel beginnen, werden zusammen enden. So ist die Bestellung endet ähnlich wie diese ...

1 10 100 2 20 200

Zu keinem Zeitpunkt hat die Art „Realize“, die Sie Bedeutung Subsets der Zeichenfolge, wie die variable Länge Zahlen an der Vorderseite der Zeichenfolge zuweisen. Beim Sortieren Zahl als Strings, Polsterung nach links mit Nullen, so viel wie nötig die größte Zahl decken helfen kann, aber es löst nicht wirklich das Problem, wenn Sie die Daten nicht steuern, wie in Ihrem Beispiel. In diesem Fall würde die Art sein ...

001 002 010 020 100 200

Es ist, als Text (alphabetisch), nicht als Nummern sortiert. Um dies zu umgehen Sie einen benutzerdefinierten Komparator in der Antwort wie von nsayer implementieren könnte.

Es macht einen lexikographischen Vergleich. Es vergleicht das erste Zeichen in jeder Zeichenkette, sie zu sortieren. Es vergleicht dann die zweite Reihe von solchen mit dem gleichen ersten charater. Wenn es die ‚_‘ Zeichen auf eine Zahl vergleicht, ist es mehr Wert als eine einzelne Zahl Zeichen wie 8> 7 und einer> 9. Denken Sie daran, es ein Zeichen Vergleich tut und nicht ein numerischer Vergleich.

Es gibt Möglichkeiten, Ihr eigenes Sortier Routing zu implementieren, die besser sein können Ihre Skriptnamen als umbenennen.

Wenn Ihr Skript Namen umbenennen eine Option ist, kann dies andere Script-Tools können verwendet werden. Ein Format kann sein

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

Durch Ihre ersten beiden Ziffern auf zwei Zeichen zu halten, wird der lexikographische Vergleich arbeiten.

Die Collections.sort () -Methode des docs sagt:

  

Sortiert die angegebene Liste in   aufsteigender Reihenfolge, gemäß der   natürliche Reihenfolge seiner Elemente.

Was bedeutet für Strings, die Sie die Liste in alphabetischer Reihenfolge werden bekommen. Der String 11_assign_privileges.sql kommt, bevor die Zeichenfolge 1_create_table.sql und 12_07_insert_static_data.sql kommt vor 1_create_table.sql etc. So wird das Programm wie erwartet funktioniert.

Da Zeichenfolge in einer alphabetischen Reihenfolge sortiert werden und der Unterstrich ist nach Zeichen für Zahlen. Sie haben einen Komparator, um „natürliche Ordnung“ zur Durchführung gewünschtes Ergebnis zu erzielen.

Die String-Algorithmus vergleichen vergleichen jedes Zeichen zu einem Zeitpunkt. 1 Sorten vor 2. Es spielt keine Rolle, dass es durch eine 1 oder 2 folgt.

So würde 100 vor 2 sortieren. Wenn Sie dieses Verhalten nicht möchten, müssen Sie einen Vergleich Algorithmus, der diesen Fall behandelt.

Wie schon andere gesagt haben, werden die Elemente alphabetisch nach Standard sortiert. Die Lösung ist eine konkrete Klasse java.util.Comparator definieren und als zweites Argument an die Sortier Methode übergeben. Ihr Komparator müssen die führenden ganzen Zahlen von den Saiten analysieren und vergleichen sie.

haben Collection.sort () sortieren willkürlich können Sie

Collections.sort(List list, Comparator c)  

implementieren Dann einfach einen Komparator, der die Zeichenfolge teilt und zuerst auf die Anzahl Sorten basiert und dann auf den Rest oder aber Sie wollen es sortieren.

Jeder hat bereits darauf hingewiesen, dass die Erklärung ist, dass die Saiten als Strings werden sortieren, und eine Reihe hat bereits Ihre Aufmerksamkeit auf Natural Order String-Vergleich gerichtet. Ich werde nur hinzufügen, dass es eine gute Übung ist, dass Komparator selbst, und eine große Chance, zu schreiben testgetriebene Entwicklung zu üben. Ich habe es benutzt Camp zu demonstrieren TDD bei Kodex; Dias & Code sind hier .

Sie können die IComparable-Schnittstelle hinzufügen und dann sortieren nach einem bestimmten Objekt. Wenn Sie eine Sammlung von Gegenständen von einem Geschäft zum Beispiel haben vielleicht wollen Sie dies nach Preis oder nach Kategorien sortieren usw. Wenn Sie nach dem Namen bestellen hier ein Beispiel:

beachten, wie die Arraylist mit dem Namen Eigenschaft der Elemente sortiert. Wenn Sie nicht die IComparable fügen Sie dann, wenn Sie die Sortiermethode verwenden wird es einen Fehler aus.

eingeben Bild Beschreibung hier

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;
        }
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top