เหตุใดจึงไม่มี SortedList ใน Java


502

ใน Java มีSortedSetและSortedMapอินเตอร์เฟซ ทั้งคู่เป็นของเฟรมเวิร์ก Java Collectionsและจัดเตรียมวิธีการเรียงลำดับเพื่อเข้าถึงองค์ประกอบ

อย่างไรก็ตามในความเข้าใจของฉันไม่มีSortedListใน Java คุณสามารถใช้java.util.Collections.sort()เพื่อเรียงลำดับรายการ

ความคิดใดที่ว่าทำไมมันถูกออกแบบเช่นนั้น


3
ไม่stackoverflow.com/questions/416266/sorted-collection-in-javaช่วยคุณได้อย่างไร
Nico Haase

6
แล้วผลลัพธ์ที่คุณคาดหวังเมื่อแทรกองค์ประกอบไว้ตรงกลางของรายการคืออะไร
bestsss

4
@bestsss มันจะเป็นไปได้อย่างเต็มที่ที่จะมีคลาส SortedList ซึ่งไม่ได้ใช้อินเตอร์เฟส java.util.List อ่านคำถามเพื่อสอบถามว่าทำไมไม่มีโครงสร้างข้อมูลที่รองรับฟังก์ชั่นที่ร้องขอ อย่าสับสนกับรายละเอียดที่ไม่สำคัญเช่นการตั้งชื่อ
Alderath

@Alderath โครงสร้างปกติของสิ่งนี้คือ tree (แดง / ดำ avl หรือ btree) w / ลิงก์ prev / next ก่อนหน้า / ถัดไปเพื่อรองรับการสั่งซื้อ ฉันใช้โครงสร้างที่คล้ายกันสีแดง / ดำ w / ก่อนหน้า / ลิงค์ถัดไป มันใช้งานค่อนข้างเฉพาะแม้ว่า ทรีสามารถสำรวจได้ทั้งแบบเรียงลำดับและแทรกมี O (logn) find / บรรจุ แต่ get (int) คือ O (n) เมื่อพิจารณาจากความสามารถในการใช้งานเฉพาะกลุ่มของฉันฉันคิดว่ามันถูกทิ้งไว้กับนักพัฒนาเพื่อนำไปใช้หากจำเป็น
bestsss

3
ไม่ตอบคำถาม "ทำไม" แต่วิธีแก้ปัญหาที่ง่ายที่สุดสำหรับ TreeSet คือการใช้ตัวเปรียบเทียบที่ไม่ส่งคืนค่าศูนย์เช่นint diff = this.score - that.score; return (diff == 0) ? 1 : diff; เป็นแฮ็คที่มีกลิ่นเหม็นฉันจะให้สิ่งนี้เป็นอาร์กิวเมนต์ตัวสร้างแบบไม่ระบุชื่อ
earcam

คำตอบ:


682

รายการตัววนซ้ำรับประกันก่อนอื่นว่าคุณจะได้รับองค์ประกอบของรายการตามลำดับภายในของรายการ (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ชั้นเรียนของคุณเอง

หมายเหตุ:คุณไม่ควรทำเช่นนี้

คุณสามารถเขียนคลาสรายการของคุณเองที่เรียงลำดับทุกครั้งที่คุณเพิ่มองค์ประกอบใหม่ สิ่งนี้สามารถคำนวณได้ค่อนข้างหนักขึ้นอยู่กับการนำไปใช้ของคุณและไม่มีจุดหมายเว้นแต่คุณต้องการทำแบบฝึกหัดเนื่องจากเหตุผลหลักสองข้อ:

  1. มันทำลายสัญญาที่List<E>ส่วนต่อประสานนั้นมีเพราะaddวิธีการต่าง ๆ ควรทำให้แน่ใจว่าองค์ประกอบนั้นจะอยู่ในดัชนีที่ผู้ใช้ระบุ
  2. ทำไมต้องคิดค้นล้อใหม่ คุณควรใช้ 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


12
+1 Imo นี่เป็นคำตอบที่สร้างสรรค์กว่าคำตอบที่ได้รับการโหวตมากที่สุด มันมาพร้อมกับข้อเสียเล็กน้อยสอง PriorityQueue ไม่สนับสนุนการเข้าถึงแบบสุ่ม คุณไม่สามารถมอง (elementIndex) Integer maxVal = prioQueue.peek(prioQueue.size() - 1);ดังนั้นคุณจึงไม่สามารถทำเช่น ประการที่สองถ้าคุณตั้งใจจะใช้ PriorityQueue เพียงแค่รายการที่เรียงลำดับมันจะฟังดูง่ายกว่าที่จะเห็นPriorityQueueในโค้ดมากกว่าที่ควรจะเห็นSortedListถ้าโครงสร้างข้อมูลนั้นมีอยู่จริง
Alderath

12
และหลังจากดูคำถามอื่น ๆ ที่มีคนเชื่อมโยงกับความคิดเห็นข้อเสียที่สำคัญอีกข้อหนึ่งคือตัววนซ้ำของ PriorityQueue ไม่รับประกันว่าจะคืนองค์ประกอบในลำดับใด ๆ ดังนั้นหากฉันไม่สามารถมองเห็นบางสิ่งได้วิธีเดียวที่จะพิมพ์วัตถุทั้งหมดใน PriorityQueue เพื่อที่จะโพลซ้ำ ๆ () คิวจนกว่าจะว่างเปล่า สำหรับฉันแล้วสิ่งนี้จะทำให้เส้นเขตแดนหลุดออกไป หากต้องการพิมพ์วัตถุใน PriorityQueue สองครั้งคุณต้องคัดลอก PriorityQueue ก่อนจากนั้นสำรวจ () วัตถุทั้งหมดจาก PriorityQueue ดั้งเดิมจากนั้น pol () l วัตถุทั้งหมดจากการคัดลอก
Alderath

1
อืม ... ดูเหมือนคุณจะถูก Alderath คุณไม่สามารถใช้ตัววนซ้ำของ PriorityQueue เพื่อรับองค์ประกอบตามลำดับที่คาดหวัง ดูเหมือนว่าฉันจะต้องแก้ไขคำตอบของฉัน
Spoike

7
คิวลำดับความสำคัญเป็นเพียง heap คุณสามารถเข้าถึงได้เฉพาะส่วนบนเท่านั้น imo ไม่ได้อยู่ในคำตอบของคำถาม
bestsss

1
นอกจากนี้ยังมีข้อสังเกตว่าCollections.sort()ยังช่วยให้คุณสามารถกำหนดฟังก์ชั่นเปรียบเทียบที่ใช้ในการเรียงลำดับโดยใช้Comparatorวัตถุ
Mike 'Pomax' Kamermans

71

เนื่องจากแนวคิดของรายการไม่สอดคล้องกับแนวคิดของคอลเลกชันที่เรียงลำดับโดยอัตโนมัติ จุดของรายการคือว่าหลังจากเรียกlist.add(7, elem)โทรไปจะกลับมาlist.get(7) elemด้วยรายการที่จัดเรียงอัตโนมัติองค์ประกอบอาจสิ้นสุดลงในตำแหน่งที่กำหนดเอง


26

ตั้งแต่รายการทั้งหมดที่มีอยู่แล้ว "เรียง" โดยการสั่งซื้อรายการที่ถูกเพิ่ม (FIFO การสั่งซื้อ) คุณสามารถ "รีสอร์ท" java.util.Collections.sort()พวกเขามีคำสั่งซื้ออื่นรวมทั้งการสั่งซื้อตามธรรมชาติขององค์ประกอบโดยใช้

แก้ไข:

แสดงรายการเป็นโครงสร้างข้อมูลตามสิ่งที่น่าสนใจคือการเรียงลำดับรายการที่แทรก

ชุดไม่มีข้อมูลนั้น

Listหากคุณต้องการสั่งซื้อโดยการเพิ่มเวลาการใช้งาน หากคุณต้องการที่จะสั่งซื้อโดยเกณฑ์อื่น ๆ SortedSetการใช้งาน


22
ชุดไม่อนุญาตให้ซ้ำกัน
bestsss

10
ฉันไม่คิดว่านี่เป็นคำตอบที่ดีมาก แน่นอนว่ารายการใน java API มีการเรียงลำดับเฉพาะที่กำหนดโดยเมื่อ / รายการถูกแทรก อย่างไรก็ตามการมีอยู่ของรายการที่เรียงลำดับในลักษณะที่ขึ้นอยู่กับวิธีการแทรก / เวลาไม่ได้ป้องกันการมีโครงสร้างข้อมูลอื่น ๆ ซึ่งคำสั่งจะถูกกำหนดในอีกทางหนึ่ง (เช่นโดย Comparator) โดยพื้นฐานแล้ว OP จะถามว่าทำไมไม่มีโครงสร้างข้อมูลเทียบเท่ากับ SortedSet โดยมีข้อยกเว้นว่าโครงสร้างข้อมูลควรอนุญาตให้มีองค์ประกอบหลายรายการที่เท่ากัน
Alderath

5
ดังนั้นคำถามที่ตามมาของฉันจะเป็น: " ทำไมไม่มีโครงสร้างข้อมูลที่ทำงานเหมือน SortedSet แต่สิ่งที่สามารถมีองค์ประกอบที่เท่ากันหลายองค์ประกอบ? " (และโปรดอย่าตอบ " เพราะชุดสามารถมีองค์ประกอบเดียวเท่านั้น ")
Alderath

@Alderath: ดูstackoverflow.com/questions/416266/sorted-collection-in-java ในระยะสั้น: ใช้ TreeMultiset ของ Guava
Janus Troelsen

4
รายการจะไม่ "เรียงลำดับ" แม้ว่าคุณจะใส่ "เรียงลำดับ" ในเครื่องหมายคำพูดคู่ พวกเขามีคำสั่ง
Koray Tugay

20

ชุดและแผนที่เป็นโครงสร้างข้อมูลที่ไม่ใช่เชิงเส้น รายการคือโครงสร้างข้อมูลเชิงเส้น

ป้อนคำอธิบายรูปภาพที่นี่


โครงสร้างข้อมูลแบบต้นไม้SortedSetและSortedMapส่วนต่อประสานนั้นใช้งาน TreeSetและTreeMapตามลำดับโดยใช้อัลกอริธึมการนำต้นไม้สีแดงดำ ดังนั้นจึงมั่นใจได้ว่าไม่มีรายการที่ซ้ำกัน (หรือปุ่มในกรณีของMap)

  • List ถูกเก็บรักษาไว้แล้วในการเก็บรวบรวมสั่งซื้อและโครงสร้างข้อมูลที่ใช้ดัชนีต้นไม้ไม่มีโครงสร้างข้อมูลตามดัชนี
  • Tree โดยนิยามไม่สามารถมีรายการที่ซ้ำกัน
  • ในListเราสามารถทำซ้ำได้ดังนั้นจึงไม่มีTreeList(เช่นไม่มีSortedList)
  • รายการเก็บรักษาองค์ประกอบตามลำดับการแทรก java.util.Collections.sort()ดังนั้นถ้าเราต้องการที่จะเรียงลำดับรายชื่อที่เราต้องใช้ เรียงลำดับรายการตามลำดับจากน้อยไปหามากตามลำดับธรรมชาติขององค์ประกอบ

14

JavaFX SortedList

แม้ว่ามันจะเอาในขณะที่, Java 8 Listจึงมีการเรียงลำดับ http://docs.oracle.com/javase/8/javafx/api/javafx/collections/transformation/SortedList.html

อย่างที่คุณเห็นใน javadocs มันเป็นส่วนหนึ่งของคอลเลกชันJavaFX ที่ตั้งใจจะให้มุมมองที่เรียงลำดับใน ObservableList

อัปเดต: โปรดทราบว่าด้วย Java 11 ชุดเครื่องมือ JavaFX ได้ย้ายไปอยู่ด้านนอกของ JDK และตอนนี้เป็นห้องสมุดแยก JavaFX 11 มีให้ดาวน์โหลดในรูปแบบ SDK หรือจาก MavenCentral ดูhttps://openjfx.io


2
น่าเสียดายที่ SortedList นี้ไม่ทำงานเหมือนรายการปกติ - ตัวอย่างเช่นมันไม่มี constructor เริ่มต้น (คุณต้องสร้างโดยใช้ ObservableList ไม่ว่ามันจะหมายถึงอะไร ... )
Erel Segal-Halevi

SortedList จาก JavaFX ชัดเจนสำหรับการใช้งานของ GUI-Components และเนื่องจากค่าใช้จ่ายไม่เหมาะสำหรับเพียงแค่มีรายการของวัตถุที่เรียงลำดับ นอกจากนี้ยังหมายถึงการอ้างอิงโมดูล FX ทั้งหมดแม้ว่าจะไม่ได้ใช้ GUI ในโครงการ
COBRA.cH

1
@ COBRA.cH ใช่ว่าเป็นจริง รายการเรียงลำดับที่มีประสิทธิภาพมากขึ้นอาจเป็นเสื้อคลุมบาง ๆ รอบ ๆ TreeMap ซึ่งใช้จำนวนเต็มเพื่อนับจำนวนซ้ำของคีย์ คุณสามารถใช้ TreeSet กับเครื่องมือเปรียบเทียบที่ไม่ส่งคืนค่า 0
swpalmer

ทำไมถึงลงคะแนน? คำถามเริ่มต้นด้วยการอนุมานว่าไม่มีรายการที่เรียงลำดับในไลบรารี JDK คำตอบนี้แก้ไขข้อสันนิษฐานนั้น ไม่ว่าคุณจะชอบหรือไม่ชอบการนำไปใช้ของรายการที่เรียงลำดับนี้ไม่ได้เป็นเหตุผลในการลงคะแนน คำตอบนี้ไม่แนะนำชั้นเรียนเพียงชี้ให้เห็นถึงการมีอยู่ของมัน
Basil Bourque

10

สำหรับผู้ใช้ใหม่ ณ เดือนเมษายน 2558 ตอนนี้ Android มีคลาสSortedListในไลบรารีการสนับสนุนซึ่งออกแบบมาเพื่อทำงานโดยRecyclerViewเฉพาะ นี่คือบล็อกโพสต์เกี่ยวกับมัน


1
เป็นที่น่าสังเกตว่าในขณะที่ความคิดเห็นนี้ Androids SortedList ขาดการสนับสนุนฟังก์ชั่น onItemMoved () ด้วย RecyclerView การเขียน SortedList ของตัวเองซึ่งมีประสิทธิภาพน้อยกว่าคือสิ่งที่ฉันต้องทำเพื่อให้ได้ข้อ จำกัด
Matthew

4

อีกจุดหนึ่งคือความซับซ้อนของเวลาในการแทรก สำหรับการแทรกรายการหนึ่งคาดว่าจะมีความซับซ้อนของ O (1) แต่นี่ไม่สามารถรับประกันได้ด้วยรายการที่เรียงลำดับ

และประเด็นที่สำคัญที่สุดคือรายการไม่เกี่ยวกับองค์ประกอบ ตัวอย่างเช่นคุณสามารถทำรายการของสิ่งที่ไม่ใช้หรือequalscompare


คุณสามารถมีรายการที่มีการแทรก / ลบ / ค้นหา / มี w / O (logn) แต่ไม่ได้มี (int)
bestsss

3
ประเด็นสุดท้ายไม่ใช่คำอธิบายที่ดีจริงๆ คุณสามารถทำในสิ่งที่ไม่ได้ดำเนินการSortedSet Comparableดูตัวสร้าง TreeSetนี้
Alderath

1
@Alderath - ถ้อยคำของฉันอ่อนแอเกินไป ทว่าการสังเกตเห็นว่าองค์ประกอบของเซตและกุญแจของต้นไม้ต้องเทียบเคียงได้อย่างน้อยก็เพื่อความเสมอภาคในขณะที่องค์ประกอบรายการไม่จำเป็นต้องใช้ ไม่ว่าความสัมพันธ์ในการสั่งซื้อ / ความเท่าเทียมกันสำหรับชุดและต้นไม้จะถูกนำไปใช้ในเครื่องมือเปรียบเทียบหรือที่อื่น ๆ นั้นไม่มีความสำคัญ - แต่คุณจำเป็นต้องมี
Ingo

รายการไม่รับประกัน O (1) การแทรกพวกเขารับประกัน O (1) การเข้าถึง bigocheatsheet.com
Matt Quigley

1
@Betlista คุณถูกต้อง! ฉันไม่สามารถอัปเดตความคิดเห็นของฉันได้ แต่Listอินเทอร์เฟซJava ไม่รับประกันประสิทธิภาพข้อกำหนดใด ๆ ในวิธีการ
Matt Quigley

3

คิดว่ามันเช่นนี้Listอินเตอร์เฟซที่มีวิธีการเช่น,add(int index, E element) set(int index, E element)สัญญาคือเมื่อคุณเพิ่มองค์ประกอบที่ตำแหน่ง X คุณจะพบมันที่นั่นเว้นแต่ว่าคุณจะเพิ่มหรือลบองค์ประกอบก่อนหน้านั้น

หากการใช้งานรายการใด ๆ จะจัดเก็บองค์ประกอบตามลำดับอื่นนอกเหนือจากดัชนีวิธีการรายการด้านบนจะไม่สมเหตุสมผล


2

บรรทัดแรกใน List API บอกว่ามันเป็นคอลเลกชันที่ได้รับคำสั่ง (หรือเรียกว่าลำดับ) หากคุณเรียงลำดับรายการคุณไม่สามารถรักษาลำดับได้ดังนั้นจึงไม่มี TreeList ใน Java
API บอกว่ารายการ Java ได้รับแรงบันดาลใจจาก Sequence และดูคุณสมบัติลำดับที่http://en.wikipedia.org/wiki/Sequence_(mathematics )

ไม่ได้หมายความว่าคุณไม่สามารถเรียงลำดับรายการได้ แต่ Java เข้มงวดกับคำจำกัดความของเขาและไม่ได้จัดเตรียมรายการเรียงลำดับตามค่าเริ่มต้น



2

ในกรณีที่คุณกำลังมองหาวิธีเรียงลำดับองค์ประกอบ แต่ยังสามารถเข้าถึงได้โดยใช้ดัชนีในวิธีที่มีประสิทธิภาพคุณสามารถทำสิ่งต่อไปนี้:

  1. ใช้รายการเข้าถึงแบบสุ่มสำหรับที่เก็บข้อมูล (เช่นArrayList)
  2. ตรวจสอบให้แน่ใจว่าเรียงลำดับอยู่เสมอ

จากนั้นเพื่อเพิ่มหรือลบองค์ประกอบที่คุณสามารถใช้Collections.binarySearchเพื่อรับดัชนีการแทรก / การลบ เนื่องจากรายการของคุณใช้การเข้าถึงแบบสุ่มคุณสามารถแก้ไขรายการได้อย่างมีประสิทธิภาพด้วยดัชนีที่กำหนด

ตัวอย่าง:

/**
 * @deprecated
 *      Only for demonstration purposes. Implementation is incomplete and does not 
 *      handle invalid arguments.
 */
@Deprecated
public class SortingList<E extends Comparable<E>> {
    private ArrayList<E> delegate;

    public SortingList() {
        delegate = new ArrayList<>();
    }

    public void add(E e) {
        int insertionIndex = Collections.binarySearch(delegate, e);

        // < 0 if element is not in the list, see Collections.binarySearch
        if (insertionIndex < 0) {
            insertionIndex = -(insertionIndex + 1);
        }
        else {
            // Insertion index is index of existing element, to add new element 
            // behind it increase index
            insertionIndex++;
        }

        delegate.add(insertionIndex, e);
    }

    public void remove(E e) {
        int index = Collections.binarySearch(delegate, e);
        delegate.remove(index);
    }

    public E get(int index) {
        return delegate.get(index);
    }
}

1

พิจารณาใช้การจัดทำดัชนีต้นไม้แผนที่ มันเป็นชุด TreeSet ที่ปรับปรุงแล้วของ JDK ที่ให้การเข้าถึงองค์ประกอบโดยดัชนีและค้นหาดัชนีขององค์ประกอบโดยไม่ต้องทำซ้ำหรือซ่อนรายการพื้นฐานที่สำรองข้อมูลต้นไม้ อัลกอริทึมนั้นมาจากการอัปเดตน้ำหนักของการเปลี่ยนแปลงโหนดทุกครั้งที่มีการเปลี่ยนแปลง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.