Как я могу отсортировать список по алфавиту?


Ответы:


218

Предполагая, что это строки, используйте удобный статический метод sort...

 java.util.Collections.sort(listOfCountryNames)

Если у вас есть названия стран, такие как «Великобритания», то это будет сломано.
Том Хотин - tackline

1
В этом случае вы можете передать Comparator в качестве дополнительного аргумента. Однако реализация этого компаратора была бы интересной частью.
Тило

7
Реализация Comparator = использовать java.text.Collator.getInstance
Thilo

143

Решение с Collections.sort

Если вы вынуждены использовать этот список, или если ваша программа имеет такую ​​структуру, как

  • Создать список
  • Добавьте названия некоторых стран
  • отсортировать их один раз
  • никогда не меняй этот список снова

тогда ответ Тилоса будет лучшим способом сделать это. Если вы объедините это с советом Тома Хотина - tackline , вы получите:

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и сразу же знает: это отсортированная коллекция строк без дубликатов, и я могу быть уверен, что это так в любой момент . Столько информации в короткой декларации.
  • Реальная производительность побеждает в некоторых случаях. Если вы используете Список и вставляете значения очень часто, и список может быть прочитан между этими вставками, то вам придется сортировать список после каждой вставки. Набор делает то же самое, но делает это намного быстрее.

Использование правильной коллекции для правильной задачи является ключом для написания короткого кода без ошибок. В этом случае это не так показательно, потому что вы просто сохраняете одну строку. Но я перестал считать, как часто я вижу, что кто-то использует Список, когда он хочет убедиться, что нет дубликатов, а затем сам создает эту функциональность. Или еще хуже, используя два списка, когда вам действительно нужна карта.

Не поймите меня неправильно: использование 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
это может работать как упражнение, но если бы я когда-нибудь увидел это в рабочем коде, я бы его остановил. немедленно.
Каценхут

2
@ james.garriss, ответ Лены был для простого списка строк, это для списка объектов, который содержит атрибут строки для сортировки.
Мунеб Мирза

Да, этот ответ чрезвычайно полезен при работе с объектами на производстве. Список строк не так часто встречается.
Доминик К


9

Используйте два аргумента для of 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
Не работает на языках с É è и т. Д. Вы должны удалить акценты раньше
Винсент Д.

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

Потому что метод sort (List <T>, Comparator <? Super T>) используется для сортировки указанного списка в соответствии с порядком, заданным указанным компаратором. Если вы хотите отсортировать список Emplpyee по их именам и возрасту, используйте метод сортировки коллекций (List, Comparator)

Нет, прости, я не чувствую никакой любви здесь. Вы отвечаете на другой вопрос, а именно, как отсортировать список объектов по их свойствам. Ваш код может быть полезен для этой цели, но это слишком излишне для вопроса ОП. :-(
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.