ฉันจะเรียงลำดับรายการตามตัวอักษรได้อย่างไร


คำตอบ:


218

สมมติว่าเป็น Strings ใช้วิธี static ที่สะดวกsort...

 java.util.Collections.sort(listOfCountryNames)

หากคุณมีชื่อประเทศเช่น "สหราชอาณาจักร" ก็จะถูกทำลาย
Tom Hawtin - tackline

1
ในกรณีนี้คุณสามารถส่งผ่าน Comparator เป็นอาร์กิวเมนต์พิเศษ การใช้งาน Comparator นั้นจะเป็นส่วนที่น่าสนใจ
Thilo

7
การใช้เครื่องมือเปรียบเทียบ Comparator = use java.text.Collator.getInstance
Thilo

143

วิธีแก้ปัญหาด้วย Collections.sort

หากคุณถูกบังคับให้ใช้รายการนั้นหรือหากโปรแกรมของคุณมีโครงสร้างเช่นนั้น

  • สร้างรายการ
  • เพิ่มชื่อประเทศ
  • จัดเรียงพวกเขาครั้งเดียว
  • ไม่ต้องเปลี่ยนรายการนั้นอีก

จากนั้นคำตอบของ Thilos จะเป็นวิธีที่ดีที่สุดที่จะทำ หากคุณรวมเข้ากับคำแนะนำจากTom Hawtin - 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
@TeerBeer ฉันแค่ชี้แจงเรื่องนี้ในขณะที่คุณทำมันด้วย และถ้าคุณสนใจสิ่งที่เร็วขึ้นให้ดูที่stackoverflow.com/questions/168891/…
Lena Schimmel

7
TreeSet จะไม่ถูกเรียงอย่างต่อเนื่องหากมีการเปลี่ยนแปลงรายการ
Joshua Goldberg

3
@JoshuaGoldberg ฉันคิดว่ามันจะไม่ถูกยกเลิกการเรียงลำดับ แต่จะหยุดทำงานอย่างถูกต้อง อย่างน้อยถ้าการกลายพันธุ์ของวัตถุมีผลต่อการเรียงลำดับ ชุดต้นไม้ขึ้นอยู่กับรายการที่เรียงลำดับเพื่อทำงานของมัน (เช่นการค้นหาการลบการแทรก ... )
Lena Schimmel

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

อีกทางเลือกหนึ่งคือการจัดเรียงในสถานที่ผ่าน 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

1
สิ่งนี้อาจทำงานเป็นแบบฝึกหัด แต่ถ้าฉันเคยเห็นว่าในรหัสการผลิตฉันจะขวานมัน ทันที
katzenhut

2
@ james.garriss คำตอบของ Lena มีไว้สำหรับรายการสตริงอย่างง่ายนี่คือรายการของวัตถุที่มีคุณสมบัติสตริงที่จะเรียงลำดับ
Muneeb Mirza

ใช่คำตอบนี้เป็นประโยชน์อย่างมากเมื่อทำงานในการผลิตกับวัตถุ รายชื่อ Strings นั้นไม่ธรรมดา
Dominik K


9

Collections.sortใช้สองอาร์กิวเมนต์สำหรับการของ คุณจะต้องการที่เหมาะสมComparatorว่ากรณีการปฏิบัติที่เหมาะสม (เช่นไม่คำศัพท์ไม่ UTF16 การสั่งซื้อ) java.text.Collator.getInstanceเช่นที่ผ่านพอใช้ได้


9

Collatorจนกว่าคุณจะได้เรียงลำดับสตริงในสำเนียงฟรีภาษาอังกฤษเท่านั้นคุณอาจต้องการที่จะใช้งาน มันจะถูกจัดเรียงเครื่องหมายกำกับอย่างถูกต้องสามารถละเว้นตัวพิมพ์เล็กและตัวพิมพ์ภาษาเฉพาะอื่น ๆ :

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

คุณสามารถตั้งค่าความแรงของ collatorดู 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 บรรทัดดีกว่ารหัส 1 บรรทัดในคำตอบของ Lena
james.garriss

เนื่องจากวิธีการเรียงลำดับ (List <T>, Comparator <? super T>) ใช้เพื่อเรียงลำดับรายการที่ระบุตามลำดับที่เกิดจากการเปรียบเทียบที่ระบุ เมื่อคุณต้องการเรียงลำดับรายชื่อของ Emplpyee ตามชื่อและอายุของพวกเขาจากนั้นใช้วิธีการเรียงลำดับคอลเลกชัน (รายการตัวเปรียบเทียบ)

ไม่ขอโทษไม่รู้สึกถึงความรักที่นี่ คุณกำลังตอบคำถามที่แตกต่างนั่นคือวิธีการเรียงลำดับรายชื่อของวัตถุตามคุณสมบัติของพวกเขา รหัสของคุณอาจมีประโยชน์สำหรับจุดประสงค์นั้น แต่มันเกินความจริงสำหรับคำถามของ OP :-(
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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.