คอลเลกชันที่เข้าถึงได้จากทั้งลำดับและการค้นหาคีย์

สิ่งที่ฉันติดตามคือคอลเลกชันเริ่มต้นที่ไม่เรียงลำดับซึ่งได้รับการสนับสนุนโดยอาร์เรย์หรือรายการอาร์เรย์ที่อนุญาตการค้นหาด้วยคีย์ หรือแผนที่เชื่อมโยงที่สามารถเดินทางได้ตามลำดับเวลาแทรก

กรณีดังต่อไปนี้ ฉันมีอะแดปเตอร์ที่เคลื่อนที่ผ่านคอลเลกชันผ่านตำแหน่ง และการแทรกก็เหมือนกับรายการ แต่ในขณะเดียวกัน ฉันก็อยากจะเปลี่ยนแต่ละองค์ประกอบในการค้นหาด้วยคีย์ แทนที่จะวนซ้ำทั้งรายการ

สิ่งที่ฉันไม่ต้องการคือต้องปรับใช้คอลเลกชันทั้งหมดใหม่ตั้งแต่ต้น หรือขัดขวางการเรียกอีกรายการหนึ่ง เนื่องจากนั่นจะเกิดข้อผิดพลาด


person MLProgrammer-CiM    schedule 06.02.2015    source แหล่งที่มา


คำตอบ (4)


LinkedHashMap คือทางออกที่ดีที่สุดของคุณ

มันทำงานเหมือน HashMap ที่มีรายการเชื่อมโยงสองเท่าที่ทำงานผ่านรายการ Map.Entry คุณสามารถใช้รายการเพื่อวนซ้ำได้ และการเป็น HashMap จะทำให้คุณสามารถค้นหา O(1) ได้

คุณสามารถเลือกลำดับการแทรกหรือลำดับการเข้าถึงได้

person aa333    schedule 06.02.2015
comment
ฉันจะได้รายการในตำแหน่งที่ 5 โดยไม่ต้องวนซ้ำผ่านคีย์ได้อย่างไร - person MLProgrammer-CiM; 06.02.2015
comment
ฉันอาจต้องจัดรูปแบบคำถามใหม่ ฉันกำลังใช้ ArrayMap ซึ่งให้ indexOfKey และ keyAt แก่ฉัน แต่ไม่รองรับลำดับการแทรก - person MLProgrammer-CiM; 06.02.2015
comment
คุณต้องการให้การเข้าถึงแบบสุ่มตามลำดับและ O(1) ค้นหาคีย์ที่ไม่ใช่ลำดับที่ระบุหรือไม่ - person robert_difalco; 06.02.2015
comment
ฉันรู้ว่ามันมีอะไรต้องถามเยอะมาก ฉันก็เลยไม่พบอะไรใน docu เลย - person MLProgrammer-CiM; 06.02.2015
comment
มีการใช้งาน ArrayMap ซึ่งรองรับการสั่งซื้อ แต่จะใช้ร่วมกับคลาสอื่น libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/ - person MLProgrammer-CiM; 06.02.2015
comment
การเรียก get ของ ArrayMap คือ O(n), FWIW - person Louis Wasserman; 06.02.2015
comment
ฉันไม่สามารถนึกถึงวิธีอื่นในการอนุญาตการเข้าถึงแบบจัดทำดัชนีได้ยกเว้นโดยขยาย LinkedHashMap เพื่อให้มีแผนที่สำรองพร้อมดัชนีเป็นคีย์ ไม่ทราบว่า DS ดังกล่าวมีอยู่ในห้องสมุดบางแห่งหรือไม่ แต่ฉันจะพยายามค้นหาหรือดำเนินการใช้งาน - person aa333; 06.02.2015
comment
@ aa333 นั่นคือสิ่งที่ฉันต้องการ แค่ไม่ได้นำไปใช้ด้วยตัวเองเพราะฉันเคยไปตามเส้นทางนั้นมาก่อน ดูอันที่ฉันมีด้านบนโดย LibGDX พวกเขายังได้สั่งแผนที่ - person MLProgrammer-CiM; 06.02.2015
comment
ฉันลิงก์ไว้ด้านล่าง ImmutableMap ซึ่งรองรับการดำเนินการทั้งหมดที่คุณกล่าวถึง แต่ไม่รองรับการเพิ่มหรือลบรายการ - person Louis Wasserman; 06.02.2015
comment
น่าเสียดายที่มันเป็นรายการที่ไม่แน่นอน - person MLProgrammer-CiM; 06.02.2015

LinkedHashMap จะทำให้คุณใกล้กับ O(1) พร้อมคำสั่งการแทรก

person jmj    schedule 06.02.2015

หากคุณต้องการการค้นหาที่จัดทำดัชนี O(1) เช่นเดียวกับการค้นหา O (1) โดยใช้คีย์ คุณสามารถทำได้หากคุณไม่จำเป็นต้องใส่รายการใหม่ลงในแผนที่ สร้างแผนที่เพียงครั้งเดียว (แม้ว่าอาจแก้ไขรายการใน แผนที่) โดยมี Guava's ImmutableMap ซึ่งจะรักษาลำดับการแทรกไว้ด้วย เช่นเดียวกับ Map ปกติ คุณสามารถค้นหาโดยใช้คีย์ได้ และคุณยังสามารถทำ map.values().asList().get(i) ได้ด้วย ซึ่งจะดึงองค์ประกอบออกมาในเวลาคงที่ อย่างไรก็ตามฉันไม่เชื่อว่ามีอะไรใน JDK ที่ทำทั้งสองอย่างได้

person Louis Wasserman    schedule 06.02.2015

จากความคิดเห็น @ aa333 ฉันได้ดำเนินการใช้งานของตัวเอง อาจไม่สมบูรณ์ดังนั้นจึงยินดีรับข้อเสนอแนะ

https://gist.github.com/anonymous/7a93535a3cfb63623a54

ผ่านกรณีทดสอบ Q&D นี้:

public static void main(String[] args) {
    Map<String, String> preMap = new HashMap<String, String>();
    preMap.put("subZero", "-1");
    preMap.put("zero", "0");
    IterableLinkedMap<String, String> map = new IterableLinkedMap<String, String>();
    map.putAll(preMap);
    map.put("one", "1");
    map.put("two", "2");
    map.put("three", "3");
    map.put("four", "4");
    map.put("five", "5");
    map.put("six", "6");
    map.remove("three");
    map.put("eight", "8");
    map.put("seven", "7");
    map.remove("one");
    map.put("three", "33");
    map.put("five", "actually five");
    for (int i = 0; i < map.size(); i++){
        System.out.println(map.getPosition(i));
    }
    map.clear();
    System.out.println(map.getPosition(0));
}

ผลลัพธ์:

0
-1
2
4
actually five
6
8
7
33
null
person MLProgrammer-CiM    schedule 07.02.2015
comment
มันเป็นจุดเริ่มต้น แต่จำเป็นต้องมีสิ่งต่างๆ เพิ่มเติมเพื่อให้ทำงานใน O(1) สำหรับการแทรกและการค้นหาทั้งตำแหน่งและคีย์ ต้นทุนคือการลบคือ O(n) ซึ่งเป็นราคาเล็กน้อยที่ต้องจ่าย IMO - person MLProgrammer-CiM; 09.02.2015