เป็นไปได้ไหมที่จะเปลี่ยนชื่อคีย์ Hashmap


92

ฉันกำลังหาวิธีเปลี่ยนชื่อคีย์ Hashmap แต่ไม่รู้ว่าเป็นไปได้ไหมใน Java


11
เอ้ยฉันหวังว่าจะไม่ การลบและการป้อนคู่คีย์ / ค่าใหม่ดูเหมือนจะเป็นหนทางที่จะไป โปรดทราบว่าโดยปกติคุณก็จัดการการอ้างอิงในแผนที่อยู่แล้ว
Maarten Bodewes

4
โปรดอย่าแก้ไขคีย์ของรายการแฮช! หากคุณโชคดีคุณจะเปลี่ยนเป็นบางอย่างที่มีแฮชโค้ดเดียวกันและคุณจะต้องพยายามหาสาเหตุว่าเกิดอะไรขึ้น หากคุณโชคไม่ดีคุณจะได้รับรายการที่หาไม่พบ (ไม่ใช่จนกว่าจะมีการสร้างตารางใหม่ทั้งหมด) การถอด / ใส่เข้าไปใหม่นั้นปลอดภัยกว่ามากและควรมีราคาถูกมาก (เป็นข้อมูลอ้างอิงทั้งหมด)
Donal Fellows

คำตอบ:


140

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

Object obj = map.remove("oldKey");
map.put("newKey", obj);

61
+1. และง่ายที่สุดในการอ่านmap.put( "newKey", map.remove( "oldKey" ) );และให้มีoldKey
Ravinder Reddy

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

3
สำหรับ javac 1.8.0_45 เวอร์ชันหนึ่งบรรทัดจะสั้นลงสองไบต์ซึ่งทำให้ฉันประหลาดใจ น่ารำคาญยิ่งกว่ากับยาชื่อสามัญที่คุณไม่สามารถส่งผ่านobjไปได้putโดยไม่ต้องแคสต์หรือประกาศว่าเป็นประเภทอื่น แต่แน่นอนว่าส่งผ่านผลremoveงานโดยตรง
Samuel Edwin Ward

1
แต่จะเปลี่ยนชื่อคีย์ทั้งหมดได้อย่างไร
gstackoverflow

4
มันจะนำไปสู่ ​​ConcurrentModificationException
gstackoverflow

20
hashMap.put("New_Key", hashMap.remove("Old_Key"));

สิ่งนี้จะทำในสิ่งที่คุณต้องการ แต่คุณจะสังเกตเห็นว่าตำแหน่งของคีย์เปลี่ยนไป


@Vins ทบทวนเอกสารอีกครั้งโปรด: D ลบ () จะส่งคืนวัตถุตรวจสอบบทช่วยสอน
Mohamed Zakaria El-Zoghbi

1
ฉันไม่ดีฉันได้ลบความคิดเห็นของฉันและโหวตให้แล้ว ขอโทษด้วยกับเรื่องนั้น.
Vins

19

กำหนดค่าของคีย์ซึ่งจำเป็นต้องเปลี่ยนชื่อให้กับคีย์ใหม่ และลบคีย์เก่า.

hashMap.put("New_Key", hashMap.get("Old_Key"));
hashMap.remove("Old_Key");

10

คุณไม่สามารถเปลี่ยนชื่อ / แก้ไขแฮชแมปได้keyเมื่อเพิ่มแล้ว

วิธีเดียวคือการลบ / ลบkeyและแทรกใหม่keyและvalueจับคู่

เหตุผล : ใน HashMap การดำเนินงานภายใน HashMapทำเครื่องหมายปรับปรุงเป็นkeyfinal

static class Entry<K ,V> implements Map.Entry<K ,V>
{
    final K key;
    V value;
    Entry<K ,V> next;
    final int hash;
    ...//More code goes here
}

สำหรับการอ้างอิง: HashMap


นี่เป็นคำตอบที่ดีที่สุดในความคิดของฉันเนื่องจากไม่สามารถเปลี่ยนชื่อคีย์ได้
Wolfson

4

คุณไม่ได้เปลี่ยนชื่อคีย์แฮชแมปคุณต้องแทรกรายการใหม่ด้วยคีย์ใหม่และลบคีย์เก่า


2

ฉันขอยืนยันว่าสาระสำคัญของคีย์ hasmap มีไว้เพื่อจุดประสงค์ในการเข้าถึงดัชนีและไม่มีอะไรเพิ่มเติม แต่นี่คือการแฮ็ก: การสร้างคลาสคีย์ห่อหุ้มรอบค่าของคีย์เพื่อให้วัตถุห่อหุ้มคีย์กลายเป็นคีย์แฮชแมปสำหรับการเข้าถึงดัชนีดังนั้นคุณ อาจเข้าถึงและเปลี่ยนแปลงค่าของออบเจ็กต์คีย์ - ห่อหุ้มสำหรับความต้องการเฉพาะของคุณ

public class KeyWrapper<T>{

      private T key;
      public KeyWrapper(T key){
         this.key=key;
       }

      public void rename(T newkey){
              this.key=newkey;
       }

}

ตัวอย่าง

   HashMap<KeyWrapper,String> hashmap=new HashMap<>();
   KeyWrapper key=new KeyWrapper("cool-key");
   hashmap.put(key,"value");
   key.rename("cool-key-renamed");

แม้ว่าคุณจะมีคีย์ที่ไม่มีอยู่แล้วก็สามารถรับค่าของคีย์ที่มีอยู่จากแฮชแมปได้ แต่ฉันกลัวว่ามันอาจจะผิดกฎหมายอย่างไรก็ตาม:

public  class KeyWrapper<T>{

        private T key;
        public KeyWrapper(T key){
            this.key=key;
        }

        @Override
        public boolean equals(Object o) {
            return hashCode()==o.hashCode();
        }

        @Override
        public int hashCode() {
            int hash=((String)key).length();//however you want your hash to be computed such that two different objects may share the same at some point
            return hash;
        }
    }

ตัวอย่าง

HashMap<KeyWrapper,String> hashmap=new HashMap<>();
KeyWrapper cool_key=new KeyWrapper("cool-key");
KeyWrapper fake_key=new KeyWrapper("fake-key");
hashmap.put(cool_key,"cool-value");
System.out.println("I don't believe it but its: "+hashmap.containsKey(fake_key)+" OMG!!!");

1

โปรดดูประเด็นด้านล่าง:

  1. ไม่คุณไม่สามารถเปลี่ยนชื่อkeyของที่HashMapเพิ่มครั้งเดียวได้

  2. ครั้งแรกที่คุณจะต้องลบหรือลบที่keyแล้วคุณสามารถแทรกใหม่ด้วยkeyvalue

  3. เพราะในHashMapการดำเนินงานภายในปรับปรุงที่สำคัญคือHashMapfinal


0

คุณสามารถถ้าแทนชวา HashMap พื้นเมืองของคุณจะใช้Bimap
ไม่ใช่การใช้งานแผนที่แบบเดิมและคุณต้องแน่ใจว่าเหมาะสมกับความต้องการของคุณ

bimap (หรือ "แผนที่สองทิศทาง") คือแผนที่ที่รักษาความเป็นเอกลักษณ์ของค่าต่างๆรวมทั้งคีย์ต่างๆ ข้อ จำกัด นี้ทำให้ bimaps รองรับ "มุมมองผกผัน" ซึ่งเป็น bimap อื่นที่มีรายการเดียวกันกับ bimap นี้ แต่มีคีย์และค่าที่กลับด้าน

ใช้ bimap คุณสามารถผกผันมุมมองและแทนที่คีย์ได้
กร้าทั้ง Apache Commons BidiMapและฝรั่งBiMap


0

ในกรณีของฉันมีแผนที่ที่ไม่มีคีย์จริง -> คีย์จริงดังนั้นฉันจึงต้องแทนที่ไม่ใช่เรียลด้วยเรียลในแผนที่ของฉัน (ความคิดก็เหมือนกับคนอื่น ๆ )

getFriendlyFieldsMapping().forEach((friendlyKey, realKey) ->
    if (map.containsKey(friendlyKey))
        map.put(realKey, map.remove(friendlyKey))
);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.