Як можна сортувати Список за алфавітом?


Відповіді:


218

Припускаючи, що це рядки, використовуйте зручний статичний метод sort...

 java.util.Collections.sort(listOfCountryNames)

Якщо у вас є назви країн, таких як "Великобританія", це буде порушено.
Том Хотін - тайклін

1
У цьому випадку ви можете передавати в Порівняльник як додатковий аргумент. Але реалізація цього компаратора була б цікавою частиною.
Тіло

7
Впровадження компаратора = використовуйте java.text.Collator.getInstance
Тило

143

Рішення з Collections.sort

Якщо ви змушені використовувати цей Список, або якщо ваша програма має подібну структуру

  • Створити список
  • Додайте кілька назв країн
  • сортувати їх один раз
  • ніколи більше не змінюйте цей список

тоді відповідь Тілоса буде найкращим способом це зробити. Якщо ви поєднаєте це з порадою Тома Хотіна - таклін , ви отримаєте:

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

Рішення за допомогою TreeSet

Якщо ви можете вирішити, і якщо ваша програма може стати складнішою, ви можете змінити свій код, щоб замість цього використовувати TreeSet. Цей вид колекції сортує ваші записи лише тоді, коли вони вставлені. Не потрібно дзвонити sort ().

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

Побічна примітка про те, чому я віддаю перевагу TreeSet

Це має деякі тонкі, але важливі переваги:

  • Це просто коротше. Тільки на один рядок коротший.
  • Ніколи не турбуйтеся про те , що цей список справді відсортований, тому що TreeSet завжди відсортований, незалежно від того, що ви робите.
  • Ви не можете мати повторювані записи. Залежно від вашої ситуації це може бути професіонал. Якщо вам потрібні дублікати, дотримуйтесь свого списку.
  • Досвідчений програміст дивиться на TreeSet<String> countyNamesі миттєво знає: це відсортована колекція Strings без дублікатів, і я можу бути впевнений, що це правда щоразу . Стільки інформації в короткій декларації.
  • Реальна ефективність виграє в деяких випадках. Якщо ви використовуєте Список і вкладаєте значення дуже часто, і список може читатися між цими вставками, вам доведеться сортувати список після кожного вставки. Набір робить те саме, але робить це набагато швидше.

Використання правильної колекції для правильного завдання - це ключ для написання короткого та помилкового коду. У цьому випадку це не так демонстративно, тому що ви просто зберігаєте один рядок. Але я перестала рахувати, як часто я бачу когось, хто використовує Список, коли вони хочуть переконатися, що немає дублікатів, а потім створити цю функціональність самостійно. Або ще гірше, використовуючи два списки, коли вам справді потрібна карта.

Не зрозумійте мене неправильно: Використання Collections.sort - це не помилка чи недолік. Але є багато випадків, коли TreeSet набагато чистіший.


Я не бачу жодної переваги від використання TreeSet над сортуванням.
DJClayworth

1
Добре TreeSet уникає випадкового дублювання (що може бути добре чи погано), і воно повинно бути швидшим (правда, не сильно з урахуванням розміру введення), і воно завжди буде сортуватись, а не сортуватись після всіх вхідних даних (якщо ви не сортуєте список після кожного вставити), що може мати значення, але, ймовірно, ні. Так швидше ..
TofuBeer

1
@TofuBeer Я лише роз'яснював це, коли ви це теж робили. А якщо вам дійсно цікаво, що швидше, погляньте на stackoverflow.com/questions/168891/…
Лена Шіммель

7
TreeSet не залишатиметься відсортованим, якщо елементи змінено.
Джошуа Голдберг

3
@JoshuaGoldberg Я думаю, що це буде не лише відсортовано, але й перестане працювати правильно. Принаймні, якщо мутація об'єкта впливає на його порядок сортування. Набір дерев покладається на елементи, відсортовані для виконання своїх завдань (наприклад, пошук, видалення, вставлення ...).
Лена Шіммель

29

Ви можете створити нову відсортовану копію за допомогою Java 8 Stream або Guava:

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

Ще один варіант - це сортування на місці за допомогою API колекцій:

Collections.sort(names);

28

Краще пізно, ніж ніколи! Ось як ми можемо це зробити (лише для навчальних цілей) -

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
Знову ж таки, немає жодного виправдання для всього цього коду, коли це буде робити один рядок. Дивіться відповідь Лени.
james.garriss

1
це може спрацювати як вправа, але якби я коли-небудь бачив це у виробничому коді, я б його сокирував. негайно.
katzenhut

2
@ james.garriss, відповідь Лени полягав у простому переліку рядків, у списку об'єктів, який містить атрибут рядка для сортування.
Muneeb Mirza

Так, ця відповідь надзвичайно корисна при роботі у виробництві з предметами. Список рядків не так часто.
Домінік К


9

Використовуйте два аргументи для Collections.sort. Ви хочете, щоб відповідне Comparatorставлення до випадків (тобто лексичне, а не впорядкування UTF16) було таким, як це можна отримати java.text.Collator.getInstance.


9

Якщо ви не сортуєте рядки лише на англійській мові, що не має акценту, ви, ймовірно, хочете використовувати Collator. Він буде правильно сортувати діакритичні позначки, може ігнорувати регістр та інші конкретні мови:

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

Ви можете встановити силу колектора , побачити javadoc.

Ось приклад для словацької мови, куди Šслід йти S, але в UTF Šдесь після 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

Ось що ви шукаєте

listOfCountryNames.sort(String::compareToIgnoreCase)

1
Не працює на мовах із É è тощо ... Попередньо потрібно накреслити наголоси
Vincent D.

5

Використовуючи Collections.sort(), ми можемо сортувати список.

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

вихід:

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

4

низхідний алфавіт:

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

Це те, що я шукав. По-перше, я повинен сортувати список назад до AZ, а потім ZA для порівняння. Хороша відповідь.
Джейпс Софі

1

Те саме в 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;

}
}

Але чому? Чому краще використовувати ці 50 рядків коду, ніж 1 рядок коду у відповіді Лени?
james.garriss

Тому що метод сортування (Список <T>, Порівняльник <? Супер T>) використовується для сортування зазначеного списку відповідно до порядку, індукованого вказаним компаратором. Коли ви хочете сортувати список Emplpyee за їхніми іменами та віками, тоді використовуйте метод Сортування колекцій (Список, Порівняння)

Ні, вибачте, не відчуваючи тут ніякої любові. Ви відповідаєте на інше запитання, а саме, як сортувати Список об’єктів за їх властивостями. Ваш код може бути корисним для цієї мети, але це є надмірним для питання ОП. :-(
james.garriss

-12

Ви можете спробувати використовувати метод, який я створив.

String key- буде порядок, який ви хочете, і в цьому випадку в алфавітному порядку. Просто поставте "abc ...".

String list[] - список, який ви хочете привести в порядок за допомогою ключа.

int index - встановити як 0, встановить зсув для ключа.

    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
Звичайно, навіщо використовувати java.util.Collections.sort (список), якщо я можу написати 30 рядків коду :)
Jirka

1
Чому тут стільки голосів? хтось навіть намагався запустити цей код або намагається зрозуміти використаний алгоритм?
JBoy
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.