如何按字母顺序对列表进行排序?


Answers:


217

假设这些是字符串,请使用方便的静态方法sort……

 java.util.Collections.sort(listOfCountryNames)

如果您有国家名称,例如“ UK”,那将被打破。
Tom Hawtin-大头钉

1
在这种情况下,您可以将Comparator作为附加参数传递。不过,实现该比较器将是有趣的部分。
Thilo

7
实现比较器= use java.text.Collat​​or.getInstance
Thilo

143

解决方案与Collections.sort

如果您被迫使用该列表,或者您的程序具有如下结构

  • 建立清单
  • 添加一些国家名称
  • 一次排序
  • 永远不会再更改该列表

那么Thilos的答案将是最好的方法。如果将其与Tom Hawtin-粘性线的建议相结合,您将获得:

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并立即知道:这是一个没有重复的String的排序集合,而且我可以确定这是真的。简短的声明中包含了很多信息。
  • 在某些情况下,真正的性能取胜。如果您使用列表,并且经常插入值,并且可能在这些插入之间读取列表,那么您必须在每次插入后对列表进行排序。该集合的功能相同,但是速度更快。

使用正确的集合执行正确的任务是编写简短且无错误代码的关键。在这种情况下,它不那么具示范性,因为您只保存了一行。但是我已经停止计数,当某人想要确保没有重复项时,我会看到某人使用列表的频率,然后自己构建该功能。甚至更糟的是,在您确实需要地图时使用两个列表。

不要误会我的意思:使用Collections.sort并不是错误或缺陷。但是,在许多情况下,TreeSet更加整洁。


我认为使用TreeSet优于排序没有任何优势。
DJClayworth

1
TreeSet可以避免意外重复(可能是好事也可能是坏事),并且它应该更快(尽管在输入大小上不会太大),并且它将始终排序而不是在所有输入之后排序(除非您在每个输入之后都对列表进行排序)插入)可能很重要,但可能无关紧要。这么快..
TofuBeer

1
@TofuBeer我也正在澄清,而您也正在这样做。如果你真的关心什么是快,看看stackoverflow.com/questions/168891/...
莱娜希米尔

7
如果项目可变,则TreeSet不会保持排序。
约书亚·戈德堡

3
@JoshuaGoldberg我认为它不仅会不排序,而且还会停止正常工作。至少对象的变异会影响其排序顺序。树集依赖于被排序的项目来执行其任务(例如搜索,删除,插入...)。
Lena Schimmel

28

您可以使用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); 

另一个选择是通过Collections 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 2015年

1
这可能是一个练习,但是如果我在生产代码中看到过,我会砍掉它。立即。
katzenhut

2
@ james.garriss,Lena的答案是简单的字符串列表,这是包含要排序的字符串属性的对象列表。
Muneeb Mirza '18

是的,在使用对象进行生产时,此答案非常有用。字符串列表并不常见。
Dominik K


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进行比较。好答案。
japes Sophey,

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行代码比Lena答案中的1行代码更好?
james.garriss 2015年

因为sort(List <T>,Comparator <?super T>)方法用于根据指定比较器引起的顺序对指定列表进行排序。当您要根据Emplpyee的名称和年龄对列表进行排序时,请使用Collections sort(List,Comparator)方法

不,抱歉,在这里没有任何爱。您正在回答另一个问题,即如何按对象的属性对对象列表进行排序。您的代码可能对此有用,但是对于OP的问题而言,这太过分了。:-(
james.garriss 2015年

-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
当然,如果我可以编写30行代码,为什么要使用java.util.Collections.sort(list):)
Jirka 2012年

1
为什么这里有这么多否定票?有没有人甚至试图运行此代码或试图了解所使用的算法?
JBoy 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.