Come posso ordinare un elenco in ordine alfabetico?


Risposte:


218

Supponendo che si tratti di stringhe, utilizzare il metodo statico conveniente sort...

 java.util.Collections.sort(listOfCountryNames)

Se hai nomi di paesi come "Regno Unito", questo verrà rotto.
Tom Hawtin - tackline

1
In questo caso, è possibile passare un comparatore come argomento aggiuntivo. L'implementazione di quel comparatore sarebbe comunque la parte interessante.
Thilo,

7
Implementazione del comparatore = usa java.text.Collator.getInstance
Thilo

143

Soluzione con Collections.sort

Se sei costretto a usare quell'Elenco o se il tuo programma ha una struttura simile

  • Crea elenco
  • Aggiungi alcuni nomi di paesi
  • ordinali una volta
  • non cambiare mai più quella lista

allora la risposta di Thilos sarà il modo migliore per farlo. Se lo combini con i consigli di Tom Hawtin - tackline , otterrai:

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

Soluzione con un TreeSet

Se sei libero di decidere e se la tua applicazione potrebbe diventare più complessa, puoi invece modificare il codice per utilizzare TreeSet. Questo tipo di raccolta ordina le voci appena inserite. Non è necessario chiamare sort ().

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

Nota a margine sul perché preferisco TreeSet

Questo ha alcuni vantaggi sottili ma importanti:

  • È semplicemente più breve. Solo una riga più corta, però.
  • Non preoccuparti mai questo elenco è davvero ordinato in questo momento perché un TreeSet è sempre ordinato, qualunque cosa tu faccia.
  • Non puoi avere voci duplicate. A seconda della situazione, questo può essere un pro o un contro. Se hai bisogno di duplicati, mantieni l'elenco.
  • Un programmatore esperto guarda TreeSet<String> countyNamese sa immediatamente: questa è una raccolta ordinata di stringhe senza duplicati, e posso essere sicuro che ciò sia vero in ogni momento . Tante informazioni in una breve dichiarazione.
  • Vittoria in prestazioni reali in alcuni casi. Se si utilizza un elenco e si inseriscono valori molto spesso e l'elenco può essere letto tra tali inserimenti, è necessario ordinare l'elenco dopo ogni inserimento. Il set fa lo stesso, ma lo fa molto più velocemente.

L'uso della raccolta giusta per l'attività corretta è una chiave per scrivere codice breve e privo di bug. In questo caso non è così dimostrativo, perché si salva solo una riga. Ma ho smesso di contare la frequenza con cui vedo qualcuno che utilizza un Elenco quando desidera assicurarsi che non vi siano duplicati e quindi crearlo da solo. O peggio ancora, usando due elenchi quando hai davvero bisogno di una mappa.

Non fraintendetemi: l'utilizzo di Collections.sort non è un errore o un difetto. Ma ci sono molti casi in cui TreeSet è molto più pulito.


Non vedo alcun vantaggio nell'usare TreeSet rispetto all'ordinamento.
DJClayworth,

1
Bene TreeSet evita la duplicazione accidentale (che può essere buona o cattiva) e dovrebbe essere più veloce (anche se non molto data la dimensione dell'input) e sarà sempre ordinato piuttosto che ordinato dopo tutto l'input (a meno che non si ordina l'elenco dopo ogni inserire) che può importare, ma probabilmente no.
Molto

1
@TofuBeer Stavo solo chiarendo questo mentre lo facevi anche tu. E se ti interessa davvero ciò che è più veloce, dai un'occhiata a stackoverflow.com/questions/168891/…
Lena Schimmel

7
Un TreeSet non rimarrà ordinato se gli articoli sono mutabili.
Joshua Goldberg

3
@JoshuaGoldberg Penso che non solo non verrà smistato, ma smetterà anche di funzionare correttamente. Almeno se la mutazione dell'oggetto influenza il suo ordinamento. Il set di alberi si basa sugli elementi ordinati per eseguire le sue attività (come cercare, rimuovere, inserire ...).
Lena Schimmel,

29

È possibile creare una nuova copia ordinata utilizzando Java 8 Stream o Guava:

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

Un'altra opzione è ordinare sul posto tramite l'API Collections:

Collections.sort(names);

28

Meglio tardi che mai! Ecco come possiamo farlo (solo a scopo di apprendimento) -

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
Ancora una volta, nessuna giustificazione per tutto questo codice quando una riga farà. Vedi la risposta di Lena.
james.garriss,

1
questo potrebbe funzionare come un esercizio, ma se mai lo vedessi nel codice di produzione, lo farei. subito.
Katzenhut,

2
@ james.garriss, la risposta di Lena era per un semplice elenco di stringhe, questo per l'elenco di oggetti che contiene l'attributo di stringa da ordinare.
Muneeb Mirza,

Sì, questa risposta è estremamente utile quando si lavora in produzione con oggetti. L'elenco delle stringhe non è così comune.
Dominik K,


9

Usa i due argomenti per of Collections.sort. Sarà necessario un Comparatorcaso appropriato che tratti il ​​caso appropriato (ad es. Ordinamento lessicale, non UTF16), come quello ottenibile tramite java.text.Collator.getInstance.


9

A meno che tu non stia ordinando le stringhe solo in un inglese privo di accento, probabilmente vorrai usare a Collator. Ordinerà correttamente i segni diacritici, può ignorare il caso e altre cose specifiche della lingua:

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

È possibile impostare la forza del collatore , vedere il javadoc.

Ecco un esempio per slovacco dove Šdovrebbe andare dopo S, ma in UTF Šè da qualche parte dopo 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

Ecco cosa stai cercando

listOfCountryNames.sort(String::compareToIgnoreCase)

1
Non funziona sulle lingue con É è ecc ... È necessario rimuovere gli accenti prima
Vincent D.

5

Usando Collections.sort(), possiamo ordinare un elenco.

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

produzione:

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

4

alfabeto decrescente:

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

Questo è quello che stavo cercando. Per prima cosa ho bisogno di riordinare l'elenco in AZ, quindi ZA per il confronto. Buona risposta.
japes Sophey il

1

Lo stesso in 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;

}
}

Ma perché? Perché è meglio usare queste 50 righe di codice rispetto alla 1 riga di codice nella risposta di Lena?
james.garriss,

Perché, il metodo sort (List <T>, Comparator <? Super T>) viene utilizzato per ordinare l'elenco specificato in base all'ordine indotto dal comparatore specificato. Quando vuoi ordinare un elenco di Emplpyee in base ai loro nomi ed età, usa il metodo Collezioni sort (Elenco, Comparatore)

No, scusa, non sento alcun amore qui. Stai rispondendo a una domanda diversa, vale a dire come ordinare un elenco di oggetti in base alle loro proprietà. Il codice potrebbe essere utile a tale scopo, ma è eccessivo per la domanda del PO. :-(
james.garriss

-12

Puoi provare a usare un metodo che ho creato.

String key- sarà l'ordine desiderato e in questo caso in ordine alfabetico. Basta inserire "abc ...".

String list[] - l'elenco che si desidera mettere in ordine utilizzando il tasto.

int index - impostato su 0, imposterà l'offset per il tasto.

    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
Certo, perché usare java.util.Collections.sort (elenco) se riesco a scrivere 30 righe di codice :)
Jirka

1
Perché così tanti voti negativi qui? qualcuno ha mai provato a eseguire questo codice o cercando di capire l'algoritmo utilizzato?
JBoy,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.