เป็นไปได้ไหมที่จะรับองค์ประกอบจาก HashMap ตามตำแหน่ง


101

วิธีการดึงองค์ประกอบจาก HashMap ตามตำแหน่งเป็นไปได้หรือไม่?


11
คุณหมายถึงอะไร "ตำแหน่ง"? ไม่ได้เรียงลำดับแฮชแมปดังนั้นจึงไม่มีแนวคิดเกี่ยวกับ "ตำแหน่ง" ตามปกติที่คุณจะได้รับจากบางสิ่งเช่นเวกเตอร์
จ้า

1
คุณหมายถึงคำสั่งแทรกหรือคำสั่งอื่น ๆ ?
Mark Elliot

คำตอบ:


94

HashMapsไม่สงวนลำดับ:

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

ลองดูLinkedHashMapซึ่งรับประกันลำดับการทำซ้ำที่คาดเดาได้


17
นี่ตอบคำถามไม่ได้จริงๆ คำตอบอื่น ๆ ด้านล่างมีประโยชน์มากกว่า
forresthopkinsa

6
ด้วยความเคารพเอกสารนี้อ้างถึงเอกสารที่ตอบคำถามโดยตรง
Wayne

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

ฉันไม่ทำตาม อธิบาย?
Wayne

ลิงก์ HashMap เสีย / 404
Raf

112

ใช้ LinkedHashMap และเมื่อคุณต้องการดึงข้อมูลตามตำแหน่งให้แปลงค่าเป็น ArrayList

LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<String,String>();
/* Populate */
linkedHashMap.put("key0","value0");
linkedHashMap.put("key1","value1");
linkedHashMap.put("key2","value2");
/* Get by position */
int pos = 1;
String value = (new ArrayList<String>(linkedHashMap.values())).get(pos);

3
จำเป็นเสมอในการสร้างสำเนาของคีย์จาก HashMap ??
Richard

สิ่งนี้จะสร้างวัตถุ ArrayList ใหม่ทุกครั้งที่เราดึงค่าซึ่งนำไปสู่การรั่วไหลของหน่วยความจำ
NullByte08

49

หากคุณต้องการรักษาลำดับที่คุณเพิ่มองค์ประกอบลงในแผนที่ให้ใช้LinkedHashMapตรงข้ามกับ justHashMapเป็นนอกคอกเพียง

นี่คือแนวทางที่จะช่วยให้คุณได้รับค่าจากดัชนีในแผนที่:

public Object getElementByIndex(LinkedHashMap map,int index){
    return map.get( (map.keySet().toArray())[ index ] );
}

1
ง่ายที่สุดฉันต้องบอกว่า ... แทนที่จะแปลงทุกสิ่งคุณใช้เพียงชุดคีย์ สุดยอด
kirtan403

20

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

Object[] keys = map.keySet().toArray();

จากนั้นคุณสามารถเข้าถึงแผนที่เช่น:

map.get(keys[i]);

โปรดทราบว่า arr [i] ควรเปลี่ยนเป็น: keys [i]
Mohsen Abasi

โอเคฉันมี Strings เป็นกุญแจแผนที่หากต้องการรับหนึ่งในนั้นส่วนที่สองจะเป็น:String myKey = keys[i].toString();
Orici

12

ใช้LinkedHashMap:

ตารางแฮชและการใช้งานรายการที่เชื่อมโยงของอินเทอร์เฟซแผนที่พร้อมลำดับการทำซ้ำที่คาดเดาได้ การใช้งานนี้แตกต่างจาก HashMap ตรงที่มีการเก็บรักษารายการที่เชื่อมโยงแบบทวีคูณซึ่งรันผ่านรายการทั้งหมด


27
ซึ่งจะรักษาคำสั่งซื้อ แต่คุณยังไม่สามารถเข้าถึงรายการด้วยดัชนีของพวกเขาได้ คุณต้องทำซ้ำ
Bozho

ลิงก์นี้เชื่อมต่อกับ API เวอร์ชันเก่า ฉันขอแนะนำให้เชื่อมโยงกับ Java 6 หรือ 7 API
jzd

6

ใช้ LinkedHashMap และใช้ฟังก์ชันนี้

private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();

กำหนดเช่นนี้และ.

private Entry getEntry(int id){
        Iterator iterator = map.entrySet().iterator();
        int n = 0;
        while(iterator.hasNext()){
            Entry entry = (Entry) iterator.next();
            if(n == id){
                return entry;
            }
            n ++;
        }
        return null;
    }

ฟังก์ชันสามารถส่งคืนรายการที่เลือก


3

ฉันสมมติว่าตาม 'ตำแหน่ง' คุณหมายถึงลำดับที่คุณแทรกองค์ประกอบลงใน HashMap ในกรณีนี้คุณต้องการใช้ LinkedHashMap LinkedHashMap ไม่มีวิธีการเข้าถึงอย่างไรก็ตาม คุณจะต้องเขียนสิ่งที่ชอบ

public Object getElementAt(LinkedHashMap map, int index) {
    for (Map.Entry entry : map.entrySet()) {
        if (index-- == 0) {
            return entry.value();
        }
    }
    return null;
}

3

วิธีการทำงานอีกวิธีหนึ่งคือการเปลี่ยนค่าแผนที่เป็นอาร์เรย์จากนั้นดึงองค์ประกอบที่ดัชนี การทดสอบการทำงานของ 100000 องค์ประกอบโดยการค้นหาดัชนีใน LinkedHashMap ของ 100,000 อ็อบเจ็กต์โดยใช้วิธีการต่อไปนี้นำไปสู่ผลลัพธ์ต่อไปนี้:

//My answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index){
    return map.values().toArray(new Particle[map.values().size()])[index];
} //68 965 ms

//Syd Lambert's answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index){
    return map.get( (map.keySet().toArray())[ index ] );
} //80 700 ms

ในองค์ประกอบการดึงข้อมูลทั้งหมดโดยดัชนีจาก LinkedHashMap ดูเหมือนจะใช้งานได้ค่อนข้างหนัก


2

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


2

HashMap ไม่มีแนวคิดเกี่ยวกับตำแหน่งดังนั้นจึงไม่มีวิธีรับวัตถุตามตำแหน่ง วัตถุในแผนที่ถูกตั้งค่าและรับด้วยกุญแจ


2

คุณสามารถใช้รหัสด้านล่างเพื่อรับรหัส: String [] keys = (String[]) item.keySet().toArray(new String[0]);

และรับวัตถุหรือรายการที่แทรกใน HashMap ด้วยคีย์ของรายการนี้ดังนี้: item.get(keys[position]);


2

ตามค่าเริ่มต้น java LinkedHasMap ไม่สนับสนุนการรับค่าตามตำแหน่ง ดังนั้นฉันขอแนะนำให้ไปปรับแต่งIndexedLinkedHashMap

public class IndexedLinkedHashMap<K, V> extends LinkedHashMap<K, V> {

    private ArrayList<K> keysList = new ArrayList<>();

    public void add(K key, V val) {
        super.put(key, val);
        keysList.add(key);
    }

    public void update(K key, V val) {
        super.put(key, val);
    }

    public void removeItemByKey(K key) {
        super.remove(key);
        keysList.remove(key);
    }

    public void removeItemByIndex(int index) {
        super.remove(keysList.get(index));
        keysList.remove(index);
    }

    public V getItemByIndex(int i) {
        return (V) super.get(keysList.get(i));
    }

    public int getIndexByKey(K key) {
        return keysList.indexOf(key);
    }
}

จากนั้นคุณสามารถใช้ LinkedHasMap ที่กำหนดเองนี้เป็น

IndexedLinkedHashMap<String,UserModel> indexedLinkedHashMap=new IndexedLinkedHashMap<>();

เพื่อเพิ่มค่า

indexedLinkedHashMap.add("key1",UserModel);

เพื่อ getValue ตามดัชนี

indexedLinkedHashMap.getItemByIndex(position);

1

HashMaps ไม่อนุญาตให้เข้าถึงตามตำแหน่ง แต่จะรู้เกี่ยวกับรหัสแฮชเท่านั้นและสามารถดึงค่าได้หากสามารถคำนวณรหัสแฮชของคีย์ได้ TreeMaps มีแนวคิดในการสั่งซื้อ แผนที่ Linkedhas รักษาลำดับที่เข้าสู่แผนที่


0

คุณสามารถลองใช้บางสิ่งเช่นนั้นดูที่:

Map<String, Integer> map = new LinkedHashMap<String, Integer>();
map.put("juan", 2);
map.put("pedro", 3);
map.put("pablo", 5);
map.put("iphoncio",9)

List<String> indexes = new ArrayList<String>(map.keySet()); // <== Parse

System.out.println(indexes.indexOf("juan"));     // ==> 0
System.out.println(indexes.indexOf("iphoncio"));      // ==> 3

ฉันหวังว่านี่จะเหมาะกับคุณ

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