Làm thế nào tôi có thể sắp xếp một danh sách theo thứ tự abc?


Câu trả lời:


217

Giả sử đó là các Chuỗi, hãy sử dụng phương thức tĩnh thuận tiện sort.

 java.util.Collections.sort(listOfCountryNames)

Nếu bạn có tên quốc gia như "UK" thì điều đó sẽ bị phá vỡ.
Tom Hawtin - tackline

1
Trong trường hợp này, bạn có thể chuyển vào Trình so sánh dưới dạng đối số phụ. Tuy nhiên, việc triển khai Bộ so sánh sẽ là phần thú vị.
Thilo

7
Áp dụng Trình so sánh = sử dụng java.text.Collator.getInstance
Thilo

143

Giải pháp với Collections.sort

Nếu bạn buộc phải sử dụng Danh sách đó hoặc nếu chương trình của bạn có cấu trúc như

  • Tạo danh sách
  • Thêm một số tên quốc gia
  • sắp xếp chúng một lần
  • không bao giờ thay đổi danh sách đó một lần nữa

Thilos trả lời sẽ là cách tốt nhất để làm điều đó. Nếu bạn kết hợp nó với lời khuyên từ Tom Hawtin - tackline , bạn sẽ nhận được:

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

Giải pháp với một TreeSet

Nếu bạn được tự do quyết định và nếu ứng dụng của bạn có thể trở nên phức tạp hơn, thì bạn có thể thay đổi mã của mình để sử dụng TreeSet thay thế. Loại bộ sưu tập này sắp xếp các mục của bạn ngay khi chúng được chèn. Không cần gọi sort ().

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

Lưu ý bên lề về lý do tại sao tôi thích TreeSet

Điều này có một số lợi thế tinh tế, nhưng quan trọng:

  • Nó chỉ đơn giản là ngắn hơn. Chỉ có một dòng ngắn hơn, mặc dù.
  • Không bao giờ lo lắng về việc danh sách này thực sự được sắp xếp ngay bây giờ vì một Tree Set luôn được sắp xếp, bất kể bạn làm gì.
  • Bạn không thể có các mục trùng lặp. Tùy thuộc vào tình huống của bạn, đây có thể là một pro hoặc một con. Nếu bạn cần trùng lặp, hãy bám vào Danh sách của bạn.
  • Một lập trình viên có kinh nghiệm nhìn vào TreeSet<String> countyNamesvà ngay lập tức biết: đây là một bộ sưu tập các Chuỗi được sắp xếp mà không trùng lặp và tôi có thể chắc chắn rằng điều này là đúng tại mọi thời điểm . Quá nhiều thông tin trong một tuyên bố ngắn.
  • Hiệu suất thực sự giành chiến thắng trong một số trường hợp. Nếu bạn sử dụng Danh sách và chèn giá trị rất thường xuyên và danh sách có thể được đọc giữa các lần chèn đó, thì bạn phải sắp xếp danh sách sau mỗi lần chèn. Bộ này làm tương tự, nhưng nó nhanh hơn nhiều.

Sử dụng đúng bộ sưu tập cho đúng tác vụ là chìa khóa để viết mã ngắn và không có lỗi. Nó không phải là minh chứng trong trường hợp này, bởi vì bạn chỉ lưu một dòng. Nhưng tôi đã ngừng đếm tần suất tôi thấy ai đó sử dụng Danh sách khi họ muốn đảm bảo không có bản sao, và sau đó tự xây dựng chức năng đó. Hoặc thậm chí tệ hơn, sử dụng hai Danh sách khi bạn thực sự cần Bản đồ.

Đừng hiểu sai ý tôi: Sử dụng Collections.sort không phải là lỗi hay sai sót. Nhưng có nhiều trường hợp khi TreeSet sạch hơn nhiều.


Tôi không thấy bất kỳ lợi thế nào khi sử dụng Treeset so với sắp xếp.
DJClayworth

1
Well TreeSet tránh sự trùng lặp ngẫu nhiên (có thể tốt hoặc xấu) và nó sẽ nhanh hơn (mặc dù không có nhiều kích thước đầu vào) và nó sẽ luôn được sắp xếp thay vì sắp xếp sau tất cả đầu vào (trừ khi bạn sắp xếp danh sách sau mỗi lần nhập chèn) có thể quan trọng, nhưng có lẽ không. Vì vậy, nhanh hơn ..
TofuBeer

1
@TofuBeer Tôi chỉ làm rõ điều này trong khi bạn cũng đang làm điều đó. Và nếu bạn thực sự quan tâm đến những gì nhanh hơn, hãy xem stackoverflow.com/questions/168891/ mẹo
Lena Schimmel

7
Một TreeSet sẽ không được sắp xếp nếu các mục có thể thay đổi.
Joshua Goldberg

3
@JoshuaGoldberg Tôi nghĩ rằng nó sẽ không chỉ được sắp xếp mà còn ngừng hoạt động chính xác. Ít nhất là nếu sự biến đổi của đối tượng ảnh hưởng đến thứ tự sắp xếp của nó. Bộ cây phụ thuộc vào các mục được sắp xếp để thực hiện các nhiệm vụ của nó (như tìm kiếm, xóa, chèn ...).
Lena Schimmel

28

Bạn có thể tạo một bản sao được sắp xếp mới bằng Java 8 Stream hoặc Guava:

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

Một tùy chọn khác là sắp xếp tại chỗ thông qua Bộ sưu tập API:

Collections.sort(names);

28

Muộn còn hơn không! Đây là cách chúng ta có thể làm điều đó (chỉ cho mục đích học tập) -

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
Một lần nữa, không có lời biện minh nào cho tất cả mã này khi một dòng sẽ làm. Xem câu trả lời của Lena.
james.garriss

1
điều này có thể hoạt động như một bài tập, nhưng nếu tôi từng thấy điều đó trong mã sản xuất, tôi sẽ sử dụng nó. ngay.
katzenhut

2
@ james.garriss, câu trả lời của Lena dành cho danh sách chuỗi đơn giản, đây là danh sách đối tượng chứa thuộc tính chuỗi được sắp xếp.
Muneeb Mirza

Vâng, câu trả lời này cực kỳ hữu ích khi làm việc trong sản xuất với các đối tượng. Danh sách các chuỗi không phổ biến.
Dominik K

14

Trong một dòng, sử dụng Java 8:

list.sort(Comparator.naturalOrder());

9

Sử dụng hai đối số cho Collections.sort. Bạn sẽ muốn một sự phù hợp Comparatorxử lý trường hợp thích hợp (nghĩa là từ vựng, không phải thứ tự UTF16), chẳng hạn như có thể đạt được thông qua java.text.Collator.getInstance.


9

Trừ khi bạn đang sắp xếp các chuỗi chỉ bằng tiếng Anh không có dấu, bạn có thể muốn sử dụng a Collator. Nó sẽ sắp xếp chính xác các dấu phụ, có thể bỏ qua trường hợp và các thứ cụ thể theo ngôn ngữ khác:

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

Bạn có thể đặt cường độ collator , xem javadoc.

Dưới đây là một ví dụ cho tiếng Slovak Šnên đi sau S, nhưng trong UTF Šlà một nơi nào đó sau 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

Đây là những gì bạn đang tìm kiếm

listOfCountryNames.sort(String::compareToIgnoreCase)

1
Không hoạt động trên các ngôn ngữ với É è, v.v ... Bạn cần loại bỏ các dấu trước
Vincent D.

5

Bằng cách sử dụng Collections.sort(), chúng ta có thể sắp xếp một danh sách.

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

đầu ra:

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

4

bảng chữ cái giảm dần:

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

Đây là những gì tôi đang tìm kiếm. Đầu tiên tôi cần sắp xếp danh sách trở lại AZ, rồi ZA để so sánh. Câu trả lời tốt.
japes Sophey

1

Tương tự trong 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;

}
}

Nhưng tại sao? Tại sao sử dụng 50 dòng mã này tốt hơn so với 1 dòng mã trong câu trả lời của Lena?
james.garriss 27/2/2015

Bởi vì, Phương thức sắp xếp (Danh sách <T>, Bộ so sánh <? Super T>) được sử dụng để sắp xếp danh sách đã chỉ định theo thứ tự được tạo ra bởi bộ so sánh đã chỉ định. Khi bạn muốn sắp xếp danh sách Emplpyee theo tên và tuổi của chúng, hãy sử dụng phương pháp Sắp xếp bộ sưu tập (Danh sách, Trình so sánh)

Không, xin lỗi, không cảm thấy bất kỳ tình yêu ở đây. Bạn đang trả lời một câu hỏi khác nhau, cụ thể là cách sắp xếp Danh sách các Đối tượng theo thuộc tính của chúng. Mã của bạn có thể hữu ích cho mục đích đó, nhưng nó quá mức cho câu hỏi của OP. :-(
james.garriss

-12

Bạn có thể thử sử dụng một phương pháp mà tôi đã thực hiện.

String key- sẽ là thứ tự bạn muốn và trong trường hợp này theo thứ tự abc. Chỉ cần đặt "abc ...".

String list[] - danh sách bạn muốn sắp xếp theo thứ tự bằng phím.

int index - đặt là 0, sẽ đặt bù cho khóa.

    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
Chắc chắn, tại sao nên sử dụng java.util.Collections.sort (danh sách) nếu tôi có thể viết 30 dòng mã :)
Jirka

1
Tại sao rất nhiều phiếu giảm ở đây? Có ai thậm chí đã thử chạy mã này hoặc cố gắng hiểu thuật toán được sử dụng?
JBoy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.