รายการตัววนซ้ำรับประกันก่อนอื่นว่าคุณจะได้รับองค์ประกอบของรายการตามลำดับภายในของรายการ (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()
ดังกล่าวข้างต้นการเรียงลำดับของList
s คือการจัดการโครงสร้างข้อมูล ดังนั้นสำหรับสถานการณ์ที่คุณต้องการ "แหล่งที่มาของความจริง" ที่จะถูกจัดเรียงในหลากหลายวิธีแล้วเรียงลำดับด้วยตนเองเป็นวิธีที่จะไป
คุณสามารถจัดเรียงรายการของคุณด้วย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
จะโยนUnsupportedOperationException
s