Có thể đổi tên khóa Hashmap không?


89

Tôi đang tìm cách đổi tên khóa Hashmap, nhưng tôi không biết liệu nó có khả thi trong Java hay không.


11
Chúa ơi, tôi hy vọng là không. Xóa và nhập lại cặp khóa / giá trị dường như là một cách để thực hiện. Lưu ý rằng bạn thường chỉ xử lý các tham chiếu trong chính bản đồ.
Maarten Bodewes

4
Vui lòng không sửa đổi khóa của mục nhập băm! Nếu may mắn, bạn sẽ thay đổi nó thành thứ gì đó có cùng mã băm và bạn sẽ hơi điên khi cố gắng tìm hiểu điều gì đã xảy ra; nếu bạn không may mắn, bạn sẽ kết thúc với một mục không thể tìm thấy (tốt, không phải cho đến khi xây dựng lại toàn bộ bảng tiếp theo). Gỡ bỏ / lắp lại sẽ tiết kiệm hơn nhiều và phải khá rẻ (xét cho cùng thì tất cả đều là tài liệu tham khảo).
Donal Fellows

Câu trả lời:


136

Cố gắng xóa phần tử và đặt lại phần tử với tên mới. Giả sử có các chìa khóa trong bản đồ của bạn String, nó có thể đạt được theo cách đó:

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

58
+1. Và đơn giản nhất để đọc là map.put( "newKey", map.remove( "oldKey" ) );và được cung cấp chứaoldKey
Ravinder Reddy

14
Về khả năng đọc được liên quan, tôi hoàn toàn không đồng ý, tôi thực sự muốn thấy rõ ràng rằng một đối tượng bị xóa khỏi bản đồ, và sau đó được thêm vào. Và vì OP có vẻ khá mới đối với Java, tôi quyết định đặt nó theo cách đó. Tuy nhiên, vì lợi ích của hiệu suất, phiên bản của bạn tất nhiên được ưu tiên hơn (vì tôi không nghĩ rằng trình biên dịch sẽ tối ưu hóa phiên bản của tôi theo cách của bạn).
Alexis Pigeon

3
Đối với javac 1.8.0_45, phiên bản một dòng ngắn hơn hai mã byte, điều này làm tôi ngạc nhiên. Khó chịu hơn với các generic, bạn không thể chuyển objđến putmà không truyền nó hoặc khai báo nó như một kiểu khác, nhưng tất nhiên là chuyển kết quả của các removehoạt động trực tiếp.
Samuel Edwin Ward

1
Nhưng làm thế nào để đổi tên tất cả các phím
gstackoverflow

4
Nó wiil dẫn đến ConcurrentModificationException
gstackoverflow

18

Gán giá trị của khóa cần đổi tên cho khóa mới. Và loại bỏ chìa khóa cũ.

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

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

Điều này sẽ làm những gì bạn muốn, nhưng bạn sẽ nhận thấy rằng vị trí của chìa khóa đã thay đổi.


@Vins lại các tài liệu xin vui lòng: D, remove () sẽ trả lại đối tượng, kiểm tra này tutorialspoint.com/java/util/hashmap_remove.htm
Mohamed El-Zakaria Zoghbi

1
xấu của tôi, tôi đã xóa bình luận của mình và bình chọn cho nó. Xin lỗi vì điều đó.
Vins

8

Bạn không thể đổi tên / sửa đổi khóa băm sơ đồ sau khi đã thêm.

Cách duy nhất là xóa / gỡ khóa và chèn bằng cặp khóa và giá trị mới.

Lý do : Trong triển khai nội bộ hashmap, công cụ sửa đổi khóa Hashmap được đánh dấu là cuối cùng.

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
}

Để tham khảo: HashMap


4

Bạn không đổi tên khóa hashmap, bạn phải chèn một mục mới với khóa mới và xóa khóa cũ.


2

Tôi cho rằng bản chất của các khóa hasmap là dành cho mục đích truy cập chỉ mục và không có gì hơn nhưng đây là một mẹo: tạo một lớp key-wrapper xung quanh giá trị của khóa để đối tượng key-wrapper trở thành khóa hashmap để truy cập chỉ mục, vì vậy bạn có thể truy cập và thay đổi giá trị của đối tượng key-wrapper cho các nhu cầu cụ thể của bạn:

public class KeyWrapper<T>{

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

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

}

Thí dụ

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

Mặc dù bạn cũng có thể có một khóa không tồn tại có thể lấy giá trị của một khóa hiện có từ bản đồ băm nhưng tôi sợ rằng nó có thể là tội phạm, dù sao:

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;
        }
    }

Thí dụ

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

Vui lòng xem các điểm dưới đây:

1) No,You can not rename the key of hashmap once added.

 2) Very first you have to delete or remove that key and then you can insert with new key with value.

 3) Because in hashmap internal implementation the Hashmap key modifier  is final.

0

Bạn có thể, nếu thay vì HashMap gốc Java, bạn sẽ sử dụng Bimap .
Đây không phải là cách triển khai Bản đồ truyền thống và bạn cần đảm bảo rằng nó phù hợp với nhu cầu của bạn.

Bản đồ hai chiều (hoặc "bản đồ hai chiều") là một bản đồ bảo tồn tính duy nhất của các giá trị cũng như các khóa của nó. Ràng buộc này cho phép các bản đồ nhị phân hỗ trợ "chế độ xem ngược", là một bản đồ bimap khác chứa các mục nhập giống như bản đồ này nhưng có các khóa và giá trị đảo ngược.

Sử dụng một bản đồ, bạn có thể đảo ngược chế độ xem và thay thế khóa.
Kiểm tra cả Apache Commons BidiMap và Guava BiMap .


0

Trong trường hợp của tôi có một bản đồ chứa không phải khóa thực -> khóa thực, vì vậy tôi phải thay thế không phải thực bằng thực trong bản đồ của mình (ý tưởng cũng giống như những người khác)

getFriendlyFieldsMapping().forEach((friendlyKey, realKey) ->
    if (map.containsKey(friendlyKey))
        map.put(realKey, map.remove(friendlyKey))
);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.