HashMap - รับค่าคีย์แรก


129

ด้านล่างนี้คือค่าที่มีอยู่ใน HashMap

statusName {Active=33, Renewals Completed=3, Application=15}

รหัส Java เพื่อรับคีย์แรก (เช่น Active)

Object myKey = statusName.keySet().toArray()[0];

เราจะรวบรวมคีย์แรก "ค่า" (เช่น 33) ได้อย่างไรฉันต้องการเก็บทั้ง "คีย์" และ "ค่า" ไว้ในตัวแปรแยกกัน


9
คุณทราบหรือไม่ว่าHashMapรายการไม่เรียงลำดับดังนั้น "อันดับแรก" อาจเปลี่ยนแปลงได้ทุกเมื่อที่คุณแก้ไขแผนที่
NPE

1
คุณเข้าใจหรือไม่ว่าไม่มีคำสั่งเฉพาะใน a HashMap? หากคุณปรับเปลี่ยนเลยคุณอาจได้รับผลลัพธ์ในลำดับที่แตกต่างกันอย่างสิ้นเชิง
Jon Skeet

ไม่ไม่รับประกันคำสั่งซื้อจากการรันเป็นรัน แต่ภายในเธรดเดียวกันคำสั่งสามารถเชื่อถือได้
hd1

1
@JonSkeet จริงๆแล้วนี่เป็นคำถามที่ถูกต้องจริงๆ ใน Groovy มีหลายกรณีที่คุณได้รับโครงสร้างที่ดูเหมือนรายการแผนที่กลับคืนมาโดยแต่ละแผนที่จะมีรายการเดียว จนถึงตอนนี้ฉันยังไม่พบวิธีที่ง่าย / ชัดเจน (Groovy) ในการพิมพ์ค่าทั้งหมด หากคีย์คงที่ก็ง่ายเหมือน collection แต่ละ {println it.key} พิมพ์แต่ละค่า แต่ไม่มีคีย์คงที่ก็ไม่ชัดเจน แต่ collection แต่ละ {println it.values ​​() [0]} ทำงาน ( การปรับแต่งคำตอบบางส่วนที่นี่ ... )
Bill K

@BillK: ถ้าคุณรู้ว่าแต่ละแผนที่มีรายการเดียวนั่นเป็นคำถามที่แตกต่างกันจริงๆและเป็นคำถามที่สมเหตุสมผลกว่า
Jon Skeet

คำตอบ:


251

คุณสามารถลองสิ่งนี้:

 Map<String,String> map = new HashMap<>();
 Map.Entry<String,String> entry = map.entrySet().iterator().next();
 String key = entry.getKey();
 String value = entry.getValue();

โปรดทราบว่าHashMapไม่รับประกันลำดับการแทรก ใช้ a LinkedHashMapเพื่อให้คำสั่งซื้อเหมือนเดิม

เช่น:

 Map<String,String> map = new LinkedHashMap<>();
 map.put("Active","33");
 map.put("Renewals Completed","3");
 map.put("Application","15");
 Map.Entry<String,String> entry = map.entrySet().iterator().next();
 String key= entry.getKey();
 String value=entry.getValue();
 System.out.println(key);
 System.out.println(value);

เอาท์พุท:

 Active
 33

ฉันรู้ว่านี่เป็นคำตอบที่เก่ามาก .. ซึ่งใช้ได้กับแฮชแมปที่มีคีย์และค่าเป็นสตริง แต่เมื่อลองแบบเดียวกันกับ object สำหรับค่าที่ได้รับข้อผิดพลาดในการแคสต์: com.google.gson.internal.LinkedTreeMap cannot be cast to...... คลาสของฉันซึ่งฉันระบุไว้แทนที่จะStringอยู่ในตำแหน่งที่ถูกต้อง ... ไม่สามารถหาคำตอบทางออนไลน์ได้ .. help
Blue Bot

@darthydarth คุณควรใช้ประเภทที่เหมาะสมตามบริบทของคุณ
Ruchira Gayan Ranaweera

ขอบคุณมากสำหรับการตอบรับครั้งแรก! ไม่ได้คาดหวัง ... อย่างที่สองฉันพบว่ามีปัญหาเกี่ยวกับ Generics ที่ไม่ได้บันทึกไว้ในรันไทม์ ในที่สุดฉันก็แฮ็คมันโดยใช้Gsonเพื่อแปลงค่าออบเจ็กต์เป็น a Stringแล้วแยกวิเคราะห์กลับเป็นประเภทคลาสของฉัน มันน่าเกลียด แต่ฉันไม่สามารถหาวิธีแก้ปัญหาอื่น ๆ สำหรับสิ่งที่ทำได้ง่ายในภาษาอื่น ๆ (ตอนนี้ฉันใช้ Java)
Blue Bot

แน่ใจ แต่อย่างไร มันมากเกินไปสำหรับส่วนความคิดเห็น
Blue Bot

@darthydarth คุณสามารถส่งอีเมลถึงฉัน ruchiragayan@gmail.com
Ruchira Gayan Ranaweera

66

ในการรับค่า "แรก":

map.values().toArray()[0]

ในการรับค่าของคีย์ "แรก":

map.get(map.keySet().toArray()[0])

หมายเหตุ: โค้ดด้านบนทดสอบแล้วใช้งานได้

ฉันพูดว่า "ครั้งแรก" เนื่องจากไม่ได้เรียงลำดับรายการ HashMap

อย่างไรก็ตาม LinkedHashMap จะวนซ้ำรายการตามลำดับเดียวกันกับที่แทรก - คุณสามารถใช้สิ่งนั้นสำหรับการใช้งานแผนที่ของคุณได้หากลำดับการแทรกมีความสำคัญ


ก่อนอื่นคุณต้องตรวจสอบว่าแผนที่ไม่ว่างเปล่า
ACV


7

คุณอาจลองทำเช่นนี้เพื่อรับรายการแรกทั้งหมด

Map.Entry<String, String> entry = map.entrySet().stream().findFirst().get();
String key = entry.getKey();
String value = entry.getValue();

เพื่อรับเฉพาะคีย์ของรายการแรก

String key = map.entrySet().stream().map(Map.Entry::getKey).findFirst().get();
// or better
String key = map.keySet().stream().findFirst().get();

เพื่อรับเฉพาะค่าของรายการแรก

String value = map.entrySet().stream().map(Map.Entry::getValue).findFirst().get();
// or better
String value = map.values().stream().findFirst().get();

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

Map.Entry<String, String> entry = map.entrySet().stream().skip(1).findFirst().get();
String key = map.keySet().stream().skip(1).findFirst().get();
String value = map.values().stream().skip(1).findFirst().get();

4

เราจะรวบรวมคีย์แรก "มูลค่า" ได้อย่างไร (เช่น 33)

โดยใช้youMap.get(keyYouHave)คุณจะได้รับคุณค่าของมัน

ต้องการจัดเก็บทั้ง "คีย์" และ "ค่า" ในตัวแปรแยกกัน

ได้คุณสามารถกำหนดสิ่งนั้นให้กับตัวแปรได้

รอ ......... ยังไม่จบ

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


2

โปรดทราบว่าคุณควรทราบว่าโฟลว์ตรรกะของคุณต้องไม่พึ่งพาการเข้าถึงHashMapองค์ประกอบในบางลำดับเพียงแค่ใส่เพราะHashMaps ไม่ได้รับคำสั่งCollections และนั่นไม่ใช่สิ่งที่พวกเขามุ่งหวังที่จะทำ (คุณสามารถอ่านเพิ่มเติมเกี่ยวกับคอลเลกชันบทกวีและตัวเรียงลำดับได้ในโพสต์นี้ )

กลับไปที่โพสต์คุณทำงานไปแล้วครึ่งหนึ่งโดยการโหลดคีย์องค์ประกอบแรก:

Object myKey = statusName.keySet().toArray()[0];

เพียงโทรmap.get(key)เพื่อรับค่าตามลำดับ:

Object myValue = statusName.get(myKey);

1

โปรดจำไว้ว่าลำดับการแทรกไม่ได้รับการเคารพในแผนที่โดยทั่วไปพูด ลองสิ่งนี้:

    /**
     * Get the first element of a map. A map doesn't guarantee the insertion order
     * @param map
     * @param <E>
     * @param <K>
     * @return
     */
    public static <E,K> K getFirstKeyValue(Map<E,K> map){
        K value = null;
        if(map != null && map.size() > 0){
            Map.Entry<E,K> entry =  map.entrySet().iterator().next();
            if(entry != null)
                value = entry.getValue();
        }
        return  value;
    }

ฉันจะใช้สิ่งนี้ก็ต่อเมื่อฉันแน่ใจmap.size() == 1แล้ว


1

ปรับปรุงคำตอบของ whoami เนื่องจากfindFirst()ส่งคืน an Optionalจึงเป็นแนวทางปฏิบัติที่ดีในการตรวจสอบว่ามีค่าหรือไม่

 var optional = pair.keySet().stream().findFirst();

 if (!optional.isPresent()) {
    return;
 }

 var key = optional.get();

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


0

เป็นวิธีที่ดีในการทำเช่นนี้ :)

Map<Integer,JsonObject> requestOutput = getRequestOutput(client,post);
int statusCode = requestOutput.keySet().stream().findFirst().orElseThrow(() -> new RuntimeException("Empty"));

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