รายการตัววนซ้ำรับประกันก่อนอื่นว่าคุณจะได้รับองค์ประกอบของรายการตามลำดับภายในของรายการ (aka. คำสั่งแทรก ) โดยเฉพาะอย่างยิ่งมันอยู่ในลำดับที่คุณใส่องค์ประกอบหรือวิธีที่คุณจัดการรายการ การเรียงลำดับสามารถมองเห็นเป็นการจัดการโครงสร้างข้อมูลและมีหลายวิธีในการเรียงลำดับรายการ
ฉันจะสั่งซื้อตามลำดับของประโยชน์ตามที่ฉันเห็น:
1. พิจารณาใช้SetหรือBagคอลเล็กชันแทน
หมายเหตุ:ฉันใส่ตัวเลือกนี้ไว้ที่ด้านบนเพราะนี่คือสิ่งที่คุณต้องการทำอยู่แล้ว
ชุดที่เรียงลำดับจะเรียงลำดับคอลเลกชันโดยอัตโนมัติเมื่อแทรกซึ่งหมายความว่าจะเรียงลำดับขณะที่คุณเพิ่มองค์ประกอบลงในคอลเลกชัน นอกจากนี้ยังหมายความว่าคุณไม่จำเป็นต้องเรียงลำดับด้วยตนเอง
นอกจากนี้หากคุณแน่ใจว่าคุณไม่จำเป็นต้องกังวลเกี่ยวกับ (หรือมี) องค์ประกอบที่ซ้ำกันคุณสามารถใช้TreeSet<T>แทน มันใช้SortedSetและNavigableSetอินเทอร์เฟซและทำงานตามที่คุณคาดหวังจากรายการ:
TreeSet<String> set = new TreeSet<String>();
set.add("lol");
set.add("cat");
// automatically sorts natural order when adding
for (String s : set) {
System.out.println(s);
}
// Prints out "cat" and "lol"
Comparator<T>หากคุณไม่ต้องการสั่งซื้อธรรมชาติที่คุณสามารถใช้พารามิเตอร์สร้างที่ใช้
อีกวิธีหนึ่งคือคุณสามารถใช้Multisets (หรือที่เรียกว่ากระเป๋า )ซึ่งเป็นSetองค์ประกอบที่อนุญาตให้ใช้องค์ประกอบที่ซ้ำกันแทนและมีการใช้งานของบุคคลที่สาม สิ่งที่สะดุดตาที่สุดจากห้องสมุดของ Guavaคือ a TreeMultiset, มันทำงานได้ดีเหมือนTreeSetกัน
2. เรียงลำดับรายการของคุณด้วย Collections.sort()
ดังกล่าวข้างต้นการเรียงลำดับของLists คือการจัดการโครงสร้างข้อมูล ดังนั้นสำหรับสถานการณ์ที่คุณต้องการ "แหล่งที่มาของความจริง" ที่จะถูกจัดเรียงในหลากหลายวิธีแล้วเรียงลำดับด้วยตนเองเป็นวิธีที่จะไป
คุณสามารถจัดเรียงรายการของคุณด้วยjava.util.Collections.sort()วิธีการ นี่คือตัวอย่างโค้ดเกี่ยวกับวิธีการ:
List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");
Collections.sort(strings);
for (String s : strings) {
System.out.println(s);
}
// Prints out "cat" and "lol"
การใช้เครื่องมือเปรียบเทียบ
หนึ่งประโยชน์ที่ชัดเจนคือการที่คุณอาจจะใช้Comparatorในsortวิธีการ Java ยังมีการใช้งานบางอย่างสำหรับComparatorเช่นCollatorที่เป็นประโยชน์สำหรับสตริงการเรียงลำดับที่มีความสำคัญสถานที่ นี่คือตัวอย่างหนึ่ง:
Collator usCollator = Collator.getInstance(Locale.US);
usCollator.setStrength(Collator.PRIMARY); // ignores casing
Collections.sort(strings, usCollator);
การเรียงลำดับในสภาพแวดล้อมที่เกิดขึ้นพร้อมกัน
โปรดทราบว่าการใช้sortวิธีนี้ไม่เป็นมิตรในสภาพแวดล้อมที่เกิดขึ้นพร้อมกันเนื่องจากจะมีการจัดการอินสแตนซ์การรวบรวมและคุณควรพิจารณาใช้คอลเล็กชันที่ไม่เปลี่ยนรูปแทน นี่คือสิ่งที่ Guava จัดให้มีในOrderingชั้นเรียนและเป็นสายการบินเดียวที่เรียบง่าย:
List<string> sorted = Ordering.natural().sortedCopy(strings);
3. ตัดรายการของคุณด้วย java.util.PriorityQueue
แม้ว่าจะไม่มีรายการเรียงใน Java แต่มีคิวเรียงซึ่งอาจจะทำงานได้ดีสำหรับคุณ มันเป็นjava.util.PriorityQueueคลาส
Nico Haase เชื่อมโยงความคิดเห็นกับคำถามที่เกี่ยวข้องที่ตอบคำถามนี้ด้วย
ในคอลเลกชันที่เรียงลำดับคุณมักจะไม่ต้องการจัดการโครงสร้างข้อมูลภายในซึ่งเป็นสาเหตุที่ PriorityQueue ไม่ใช้ส่วนติดต่อรายการ (เพราะจะทำให้คุณเข้าถึงองค์ประกอบโดยตรง)
Caveat บนตัวPriorityQueueวนซ้ำ
PriorityQueueการดำเนินการในชั้นเรียนIterable<E>และCollection<E>การเชื่อมต่อเพื่อที่จะสามารถซ้ำได้ตามปกติ อย่างไรก็ตาม iterator ไม่รับประกันว่าจะคืนองค์ประกอบในลำดับที่เรียง แต่ (ตามที่ Alderath ชี้ให้เห็นในความคิดเห็น) คุณต้องpoll()เข้าคิวจนกว่าจะว่างเปล่า
โปรดทราบว่าคุณสามารถแปลงรายการเป็นคิวลำดับความสำคัญผ่านConstructor ที่รับการรวบรวม :
List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");
PriorityQueue<String> sortedStrings = new PriorityQueue(strings);
while(!sortedStrings.isEmpty()) {
System.out.println(sortedStrings.poll());
}
// Prints out "cat" and "lol"
4. เขียนSortedListชั้นเรียนของคุณเอง
หมายเหตุ:คุณไม่ควรทำเช่นนี้
คุณสามารถเขียนคลาสรายการของคุณเองที่เรียงลำดับทุกครั้งที่คุณเพิ่มองค์ประกอบใหม่ สิ่งนี้สามารถคำนวณได้ค่อนข้างหนักขึ้นอยู่กับการนำไปใช้ของคุณและไม่มีจุดหมายเว้นแต่คุณต้องการทำแบบฝึกหัดเนื่องจากเหตุผลหลักสองข้อ:
- มันทำลายสัญญาที่
List<E>ส่วนต่อประสานนั้นมีเพราะaddวิธีการต่าง ๆ ควรทำให้แน่ใจว่าองค์ประกอบนั้นจะอยู่ในดัชนีที่ผู้ใช้ระบุ
- ทำไมต้องคิดค้นล้อใหม่ คุณควรใช้ TreeSet หรือ Multisets แทนดังที่กล่าวไว้ในจุดแรกด้านบน
อย่างไรก็ตามหากคุณต้องการทำแบบฝึกหัดที่นี่เป็นตัวอย่างโค้ดเพื่อให้คุณเริ่มต้นใช้AbstractListคลาสนามธรรม:
public class SortedList<E> extends AbstractList<E> {
private ArrayList<E> internalList = new ArrayList<E>();
// Note that add(E e) in AbstractList is calling this one
@Override
public void add(int position, E e) {
internalList.add(e);
Collections.sort(internalList, null);
}
@Override
public E get(int i) {
return internalList.get(i);
}
@Override
public int size() {
return internalList.size();
}
}
โปรดทราบว่าหากคุณยังไม่ได้แทนที่วิธีที่คุณต้องการการใช้งานเริ่มต้นจากAbstractListจะโยนUnsupportedOperationExceptions