Wie kann ich eine Liste alphabetisch sortieren?

Antworten:

217

Angenommen, dies sind Strings, verwenden Sie die bequeme statische Methode sort

 java.util.Collections.sort(listOfCountryNames)
Thilo
quelle
Wenn Sie Ländernamen wie "UK" haben, wird das kaputt gehen.
Tom Hawtin - Tackline
1
In diesem Fall können Sie einen Komparator als zusätzliches Argument übergeben. Die Implementierung dieses Komparators wäre jedoch der interessante Teil.
Thilo
7
Implementieren des Komparators = Verwenden Sie java.text.Collator.getInstance
Thilo
143

Lösung mit Collections.sort

Wenn Sie gezwungen sind, diese Liste zu verwenden, oder wenn Ihr Programm eine Struktur wie hat

  • Erstelle Liste
  • Fügen Sie einige Ländernamen hinzu
  • sortiere sie einmal
  • Ändern Sie diese Liste nie wieder

dann ist Thilos Antwort der beste Weg, dies zu tun. Wenn Sie es mit dem Rat von Tom Hawtin - Tackline kombinieren , erhalten Sie:

java.util.Collections.sort(listOfCountryNames, Collator.getInstance());

Lösung mit einem TreeSet

Wenn Sie frei entscheiden können und Ihre Anwendung komplexer wird, können Sie Ihren Code ändern, um stattdessen ein TreeSet zu verwenden. Diese Art der Sammlung sortiert Ihre Einträge nur dann, wenn sie eingefügt werden. Sort () muss nicht aufgerufen werden.

Collection<String> countryNames = 
    new TreeSet<String>(Collator.getInstance());
countryNames.add("UK");
countryNames.add("Germany");
countryNames.add("Australia");
// Tada... sorted.

Randnotiz, warum ich das TreeSet bevorzuge

Dies hat einige subtile, aber wichtige Vorteile:

  • Es ist einfach kürzer. Nur eine Zeile kürzer.
  • Machen Sie sich keine Sorgen, diese Liste ist im Moment wirklich sortiert, da ein TreeSet immer sortiert ist, egal was Sie tun.
  • Sie können keine doppelten Einträge haben. Abhängig von Ihrer Situation kann dies ein Pro oder ein Contra sein. Wenn Sie Duplikate benötigen, bleiben Sie bei Ihrer Liste.
  • Ein erfahrener Programmierer schaut zu TreeSet<String> countyNamesund weiß sofort: Dies ist eine sortierte Sammlung von Strings ohne Duplikate, und ich kann sicher sein, dass dies in jedem Moment zutrifft . So viele Informationen in einer kurzen Erklärung.
  • In einigen Fällen gewinnt echte Leistung. Wenn Sie eine Liste verwenden und sehr oft Werte einfügen und die Liste möglicherweise zwischen diesen Einfügungen gelesen wird, müssen Sie die Liste nach jeder Einfügung sortieren. Das Set macht das Gleiche, aber viel schneller.

Die Verwendung der richtigen Sammlung für die richtige Aufgabe ist ein Schlüssel zum Schreiben von kurzem und fehlerfreiem Code. Dies ist in diesem Fall nicht so demonstrativ, da Sie nur eine Zeile speichern. Aber ich habe aufgehört zu zählen, wie oft ich jemanden sehe, der eine Liste verwendet, wenn er sicherstellen möchte, dass keine Duplikate vorhanden sind, und diese Funktionalität dann selbst erstellt. Oder noch schlimmer: Verwenden Sie zwei Listen, wenn Sie wirklich eine Karte benötigen.

Versteh mich nicht falsch: Die Verwendung von Collections.sort ist kein Fehler oder Fehler. Es gibt jedoch viele Fälle, in denen das TreeSet viel sauberer ist.

Lena Schimmel
quelle
Ich sehe keinen Vorteil darin, TreeSet gegenüber Sortieren zu verwenden.
DJClayworth
1
Nun, TreeSet vermeidet versehentliches Duplizieren (was gut oder schlecht sein kann) und sollte schneller sein (wenn auch angesichts der Größe der Eingabe nicht viel), und es wird immer sortiert und nicht nach allen Eingaben sortiert (es sei denn, Sie sortieren die Liste nach jeder Eingabe einfügen), was wichtig sein kann, aber wahrscheinlich nicht. Also schneller ..
TofuBeer
1
@TofuBeer Ich habe das gerade geklärt, während du es auch getan hast. Und wenn Sie sich wirklich dafür interessieren, was schneller ist, schauen Sie sich stackoverflow.com/questions/168891/… an
Lena Schimmel
7
Ein TreeSet bleibt nicht sortiert, wenn die Elemente veränderbar sind.
Joshua Goldberg
3
@JoshuaGoldberg Ich denke, es wird nicht nur nicht sortiert, es wird auch nicht mehr richtig funktionieren. Zumindest wenn die Mutation des Objekts seine Sortierreihenfolge beeinflusst. Der Baumsatz basiert auf den Elementen, die sortiert werden, um seine Aufgaben auszuführen (wie Suchen, Entfernen, Einfügen ...).
Lena Schimmel
28

Sie können mit Java 8 Stream oder Guava eine neue sortierte Kopie erstellen:

// Java 8 version
List<String> sortedNames = names.stream().sorted().collect(Collectors.toList());
// Guava version
List<String> sortedNames = Ordering.natural().sortedCopy(names); 

Eine weitere Option ist das Sortieren vor Ort über die Sammlungs-API:

Collections.sort(names);
Vitalii Fedorenko
quelle
28

Besser spät als nie! Hier ist, wie wir es tun können (nur zu Lernzwecken) -

import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class SoftDrink {
    String name;
    String color;
    int volume; 

    SoftDrink (String name, String color, int volume) {
        this.name = name;
        this.color = color;
        this.volume = volume;
    }
}

public class ListItemComparision {
    public static void main (String...arg) {
        List<SoftDrink> softDrinkList = new ArrayList<SoftDrink>() ;
        softDrinkList .add(new SoftDrink("Faygo", "ColorOne", 4));
        softDrinkList .add(new SoftDrink("Fanta",  "ColorTwo", 3));
        softDrinkList .add(new SoftDrink("Frooti", "ColorThree", 2));       
        softDrinkList .add(new SoftDrink("Freshie", "ColorFour", 1));

        Collections.sort(softDrinkList, new Comparator() {
            @Override
            public int compare(Object softDrinkOne, Object softDrinkTwo) {
                //use instanceof to verify the references are indeed of the type in question
                return ((SoftDrink)softDrinkOne).name
                        .compareTo(((SoftDrink)softDrinkTwo).name);
            }
        }); 
        for (SoftDrink sd : softDrinkList) {
            System.out.println(sd.name + " - " + sd.color + " - " + sd.volume);
        }
        Collections.sort(softDrinkList, new Comparator() {
            @Override
            public int compare(Object softDrinkOne, Object softDrinkTwo) {
                //comparision for primitive int uses compareTo of the wrapper Integer
                return(new Integer(((SoftDrink)softDrinkOne).volume))
                        .compareTo(((SoftDrink)softDrinkTwo).volume);
            }
        });

        for (SoftDrink sd : softDrinkList) {
            System.out.println(sd.volume + " - " + sd.color + " - " + sd.name);
        }   
    }
}
Tirath
quelle
4
Wieder keine Rechtfertigung für all diesen Code, wenn eine Zeile ausreicht. Siehe Lenas Antwort.
James.garriss
1
Das mag als Übung funktionieren, aber wenn ich das jemals im Produktionscode sehen würde, würde ich es streichen. sofort.
Katzenhut
2
@ james.garriss, Lenas Antwort war für eine einfache Liste von Zeichenfolgen, dies ist für eine Liste von Objekten, die zu sortierende Zeichenfolgenattribute enthalten.
Muneeb Mirza
Ja, diese Antwort ist äußerst hilfreich, wenn Sie in der Produktion mit Objekten arbeiten. Liste der Zeichenfolgen ist nicht so häufig.
Dominik K
14

In einer Zeile mit Java 8:

list.sort(Comparator.naturalOrder());
Victor Petit
quelle
9

Verwenden Sie die beiden Argumente für von Collections.sort. Sie möchten eine geeignete Comparator, die Groß- und Kleinschreibung behandelt (dh lexikalische, nicht UTF16-Reihenfolge), wie die, die über erhältlich ist java.text.Collator.getInstance.

Tom Hawtin - Tackline
quelle
9

Wenn Sie Zeichenfolgen nicht nur in akzentfreiem Englisch sortieren, möchten Sie wahrscheinlich a verwenden Collator. Es sortiert diakritische Zeichen korrekt, kann Groß- und Kleinschreibung und andere sprachspezifische Dinge ignorieren:

Collections.sort(countries, Collator.getInstance(new Locale(languageCode)));

Sie können die Stärke des Kollators einstellen , siehe Javadoc.

Hier ist ein Beispiel für Slowakisch, wohin Šes gehen soll S, aber in UTF Šist es irgendwo danach Z:

List<String> countries = Arrays.asList("Slovensko", "Švédsko", "Turecko");

Collections.sort(countries);
System.out.println(countries); // outputs [Slovensko, Turecko, Švédsko]

Collections.sort(countries, Collator.getInstance(new Locale("sk")));
System.out.println(countries); // outputs [Slovensko, Švédsko, Turecko]
Oliv
quelle
7

Hier ist was Sie suchen

listOfCountryNames.sort(String::compareToIgnoreCase)
prashant
quelle
1
Funktioniert nicht bei Sprachen mit É è etc ... Sie müssen vorher Akzente
Vincent D.
5

Mit Collections.sort()können wir eine Liste sortieren.

public class EmployeeList {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        List<String> empNames= new ArrayList<String>();

        empNames.add("sudheer");
        empNames.add("kumar");
        empNames.add("surendra");
        empNames.add("kb");

        if(!empNames.isEmpty()){

            for(String emp:empNames){

                System.out.println(emp);
            }

            Collections.sort(empNames);

            System.out.println(empNames);
        }
    }
}

Ausgabe:

sudheer
kumar
surendra
kb
[kb, kumar, sudheer, surendra]
ASR
quelle
4

absteigendes Alphabet:

List<String> list;
...
Collections.sort(list);
Collections.reverse(list);
norbDEV
quelle
Das habe ich gesucht. Zuerst muss ich die Liste zurück nach AZ und dann nach ZA zum Vergleich sortieren. Gute Antwort.
Japes Sophey
1

Gleiches gilt für JAVA 8: -

//Assecnding order
        listOfCountryNames.stream().sorted().forEach((x) -> System.out.println(x));

//Decending order
        listOfCountryNames.stream().sorted((o1, o2) -> o2.compareTo(o1)).forEach((x) -> System.out.println(x));
Opster Elasticsearch Pro-Vijay
quelle
0
//Here is sorted List alphabetically with syncronized
package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
/**
* 
* @author manoj.kumar
*/
public class SynchronizedArrayList {
static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());
@SuppressWarnings("unchecked")
public static void main(String[] args) {

List<Employee> synchronizedList = Collections.synchronizedList(new ArrayList<Employee>());
synchronizedList.add(new Employee("Aditya"));
synchronizedList.add(new Employee("Siddharth"));
synchronizedList.add(new Employee("Manoj"));
Collections.sort(synchronizedList, new Comparator() {
public int compare(Object synchronizedListOne, Object synchronizedListTwo) {
//use instanceof to verify the references are indeed of the type in question
return ((Employee)synchronizedListOne).name
.compareTo(((Employee)synchronizedListTwo).name);
}
}); 
/*for( Employee sd : synchronizedList) {
log.info("Sorted Synchronized Array List..."+sd.name);
}*/

// when iterating over a synchronized list, we need to synchronize access to the synchronized list
synchronized (synchronizedList) {
Iterator<Employee> iterator = synchronizedList.iterator();
while (iterator.hasNext()) {
log.info("Sorted Synchronized Array List Items: " + iterator.next().name);
}
}

}
}
class Employee {
String name;
Employee (String name) {
this.name = name;

}
}

quelle
Aber wieso? Warum ist es besser, diese 50 Codezeilen als die 1 Codezeile in Lenas Antwort zu verwenden?
James.garriss
Weil die Sortiermethode (Liste <T>, Komparator <? Super T>) verwendet wird, um die angegebene Liste gemäß der vom angegebenen Komparator induzierten Reihenfolge zu sortieren. Wenn Sie eine Liste der Mitarbeiter nach Namen und Alter sortieren möchten, verwenden Sie die Methode Sammlungen sortieren (Liste, Komparator)
Nein, tut mir leid, ich fühle hier keine Liebe. Sie beantworten eine andere Frage, nämlich wie eine Liste von Objekten nach ihren Eigenschaften sortiert wird. Ihr Code könnte für diesen Zweck nützlich sein, aber es ist viel zu viel für die Frage des OP. :-(
james.garriss
-12

Sie können versuchen, eine Methode zu verwenden, die ich gemacht habe.

String key- wird die gewünschte Reihenfolge sein und in diesem Fall in alphabetischer Reihenfolge. Setzen Sie einfach "abc ...".

String list[] - die Liste, die Sie mit dem Schlüssel ordnen möchten.

int index - als 0 gesetzt, setzt den Offset für die Taste.

    public static String[] order(String key, String list[], int index) {
    ArrayList<String> order_List = new ArrayList<String>();
    ArrayList<String> temp_Order_List = null;
    char[] key_char = key.toCharArray();
    for (int offset = 0; offset < key_char.length; offset++) {
        if (key_char.length >= offset + index) {
            String str = (index > 1 ? list[0].substring(0, index - 1) : "")
                    + new String(key_char, offset, 1);
            for (int i = 0; i < list.length; i++) {
                temp_Order_List = new ArrayList<String>();
                for (int k = 0; k < list.length; k++) {
                    if (!order_List.contains(list[k])
                            && !temp_Order_List.contains(list[k])) {
                        if (list[k].equalsIgnoreCase(str))
                            order_List.add(list[k]);
                        else if (list[k].toLowerCase().startsWith(str.toLowerCase())) {
                            temp_Order_List.add(list[k]);

                        }
                    }
                }
                if (temp_Order_List.size() > 0) {
                    if (temp_Order_List.size() > 1) {
                        String[] add = order(key,
                                temp_Order_List.toArray(new String[temp_Order_List
                                        .size()]), index + 1);
                        for (String s : add) {
                            order_List.add(s);
                        }
                    } else {
                        order_List.add(temp_Order_List.get(0));
                    }
                }
            }
        }
    }
    return order_List.toArray(new String[order_List.size()]);
}
Doout
quelle
32
Klar, warum java.util.Collections.sort (Liste) verwenden, wenn ich 30 Codezeilen schreiben kann :)
Jirka
1
Warum so viele Abstimmungen hier? Hat jemand versucht, diesen Code auszuführen oder den verwendeten Algorithmus zu verstehen?
JBoy