Jak mogę posortować listę alfabetycznie?


Odpowiedzi:


217

Zakładając, że są to ciągi, użyj wygodnej metody statycznej sort

 java.util.Collections.sort(listOfCountryNames)

Jeśli masz nazwy krajów, takie jak „Wielka Brytania”, zostanie to zepsute.
Tom Hawtin - tackline

1
W takim przypadku możesz przekazać Komparator jako dodatkowy argument. Interesujące byłoby jednak wdrożenie tego Komparatora.
Thilo,

7
Wdrożenie programu porównawczego = użyj java.text.Collator.getInstance
Thilo

143

Rozwiązanie z kolekcji.sort

Jeśli jesteś zmuszony do korzystania z tej listy lub jeśli twój program ma podobną strukturę

  • Sporządzać listę
  • Dodaj kilka nazw krajów
  • posortuj je raz
  • nigdy więcej nie zmieniaj tej listy

wtedy odpowiedź Thilos będzie najlepszym sposobem na zrobienie tego. Jeśli połączysz to z radą Toma Hawtina - tackline , otrzymasz:

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

Rozwiązanie z zestawem TreeSet

Jeśli możesz swobodnie decydować i twoja aplikacja może stać się bardziej złożona, możesz zmienić kod, aby zamiast tego użyć TreeSet. Ten rodzaj kolekcji sortuje wpisy tylko po ich wstawieniu. Nie trzeba wywoływać sort ().

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

Uwaga dodatkowa na temat tego, dlaczego wolę TreeSet

Ma to pewne subtelne, ale ważne zalety:

  • Jest po prostu krótszy. Jednak tylko o jeden wiersz krótszy.
  • Nie martw się, ta lista jest teraz naprawdę posortowana, ponieważ zestaw TreeSet jest zawsze sortowany, bez względu na to, co robisz.
  • Nie możesz mieć zduplikowanych wpisów. W zależności od twojej sytuacji może to być plus lub minus. Jeśli potrzebujesz duplikatów, trzymaj się swojej listy.
  • Doświadczony programista patrzy TreeSet<String> countyNamesi natychmiast wie: jest to posortowana kolekcja ciągów bez duplikatów, i mogę być pewien, że jest to prawdą w każdej chwili . Tyle informacji w krótkiej deklaracji.
  • Rzeczywista wydajność wygrywa w niektórych przypadkach. Jeśli używasz listy i wstawiasz wartości bardzo często, a listę można czytać między tymi wstawkami, musisz posortować listę po każdym wstawieniu. Zestaw robi to samo, ale robi to znacznie szybciej.

Używanie odpowiedniej kolekcji do właściwego zadania jest kluczem do pisania krótkiego i wolnego od błędów kodu. W tym przypadku nie jest tak demonstracyjny, ponieważ zapisujesz tylko jedną linię. Przestałem jednak liczyć, jak często widzę, jak ktoś korzysta z Listy, gdy chce się upewnić, że nie ma w nim nikogo, a potem sam tę funkcję buduje. Albo jeszcze gorzej, używając dwóch list, gdy naprawdę potrzebujesz mapy.

Nie zrozumcie mnie źle: używanie kolekcji.sort nie jest błędem ani wadą. Ale w wielu przypadkach TreeSet jest znacznie czystszy.


Nie widzę żadnej przewagi w korzystaniu z TreeSet nad sortowaniem.
DJClayworth,

1
Cóż, TreeSet unika przypadkowego powielania (które może być dobre lub złe) i powinno być szybsze (choć nie za bardzo biorąc pod uwagę rozmiar danych wejściowych) i zawsze będzie sortowane, a nie sortowane po wszystkich danych wejściowych (chyba że posortujesz listę po każdym insert), co może mieć znaczenie, ale prawdopodobnie nie. Tak szybciej ..
TofuBeer

1
@TofuBeer Właśnie to wyjaśniałem, kiedy ty też to robiłeś. A jeśli naprawdę zależy Ci na tym, co jest szybsze, spójrz na stackoverflow.com/questions/168891/...
Lena Schimmel

7
Zestaw TreeSet nie pozostanie posortowany, jeśli elementy można modyfikować.
Joshua Goldberg

3
@JoshuaGoldberg Myślę, że to nie tylko zostanie posortowane, ale również przestanie działać poprawnie. Przynajmniej jeśli mutacja obiektu wpływa na jego porządek sortowania. Zestaw drzew polega na sortowaniu elementów w celu wykonania swoich zadań (takich jak wyszukiwanie, usuwanie, wstawianie ...).
Lena Schimmel,

29

Możesz utworzyć nową posortowaną kopię za pomocą Java 8 Stream lub Guava:

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

Inną opcją jest sortowanie w miejscu za pośrednictwem interfejsu API kolekcji:

Collections.sort(names);

28

Lepiej późno niż wcale! Oto jak możemy to zrobić (tylko w celu uczenia się) -

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

4
Ponownie, nie ma uzasadnienia dla całego tego kodu, gdy zrobi to jedna linia. Zobacz odpowiedź Leny.
james.garriss,

1
może to działać jako ćwiczenie, ale gdybym kiedykolwiek zobaczył to w kodzie produkcyjnym, wykonałbym to. natychmiast.
katzenhut

2
@ james.garriss, odpowiedź Leny dotyczyła prostej listy ciągów, dotyczy to listy obiektów zawierających atrybut ciągu do posortowania.
Muneeb Mirza

Tak, ta odpowiedź jest wyjątkowo pomocna podczas pracy z obiektami. Lista ciągów nie jest tak powszechna.
Dominik K


9

Użyj dwóch argumentów dla Collections.sort. Będziesz potrzebował odpowiedniegoComparator który traktuje przypadek odpowiedni (tj. Robi leksykalne, a nie porządkowanie UTF16), taki jak ten, który można uzyskać java.text.Collator.getInstance.


9

O ile nie sortujesz ciągów tylko w języku angielskim bez akcentu, prawdopodobnie chcesz użyć Collator. Poprawnie sortuje znaki diakrytyczne, może ignorować wielkość liter i inne elementy specyficzne dla języka:

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

Możesz ustawić siłę zbieracza , patrz javadoc.

Oto przykład słowackiego, gdzie Šnależy iść S, ale w UTF Šjest gdzieś po 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]

7

Oto czego szukasz

listOfCountryNames.sort(String::compareToIgnoreCase)

1
Nie działa z językami z É è itp. Musisz wcześniej usunąć akcenty
Vincent D.

5

Za pomocą Collections.sort()możemy posortować listę.

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

wynik:

sudheer
kumar
surendra
kb
[kb, kumar, sudheer, surendra]

4

alfabet malejący:

List<String> list;
...
Collections.sort(list);
Collections.reverse(list);

Właśnie tego szukałem. Najpierw muszę posortować listę z powrotem do AZ, a następnie ZA do porównania. Dobra odpowiedź.
Japonki Sophey,

1

To samo w 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));

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;

}
}

Ale dlaczego? Dlaczego lepiej użyć tych 50 wierszy kodu niż 1 wiersz kodu w odpowiedzi Leny?
james.garriss

Ponieważ metoda sortowania (Lista <T>, Komparator <? Super T>) jest używana do sortowania określonej listy zgodnie z kolejnością indukowaną przez określony komparator. Jeśli chcesz posortować listę Pracowników według ich nazwisk i wieku, użyj metody Sortuj kolekcje (Lista, Komparator)

Nie, przepraszam, nie czuję tu żadnej miłości. Odpowiadasz na inne pytanie, a mianowicie, jak posortować listę obiektów według ich właściwości. Twój kod może być przydatny do tego celu, ale jest to przesada w przypadku pytania PO. :-(
james.garriss 10.04.15

-12

Możesz spróbować użyć metody, którą stworzyłem.

String key- będzie kolejność, którą chcesz, w tym przypadku alfabetycznie. Po prostu wstaw „abc ...”.

String list[] - lista, którą chcesz uporządkować za pomocą klucza.

int index - ustawiony na 0, ustawi przesunięcie dla klucza.

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

32
Jasne, po co używać java.util.Collections.sort (lista), jeśli mogę napisać 30 linii kodu :)
Jirka

1
Po co tyle głosów tutaj? czy ktoś próbował uruchomić ten kod lub próbował zrozumieć używany algorytm?
JBoy,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.