我们可以在 Java 中使用 object 作为 hashmap 的键吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45831828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 08:55:49  来源:igfitidea点击:

Can we use object as a key in hashmap in Java?

javahashmap

提问by Mahesh Kshirsagar

How to use an object as a key in a hashmap. If you use an object as key do you need to override equals and hashcode methods for that object?

如何使用对象作为哈希图中的键。如果使用对象作为键,是否需要覆盖该对象的 equals 和 hashcode 方法?

回答by Sarthak Mittal

A simple thumb rule is to use immutable objects as keysin a HashMap.

一个简单的经验法则是使用不可变对象作为键HashMap

because:

因为:

If it were mutable, then the hashcode()value or equals()condition might change, and you would never be able to retrieve the key from your HashMap.

如果它是可变的,那么hashcode()值或equals()条件可能会改变,并且您将永远无法从HashMap.

More precisely, class fields that are used to compute equals()and hashcode()should be immutable!

更确切地说,类字段被用来计算equals()hashcode()应该是一成不变的!

Now, suppose you create your own class:

现在,假设您创建了自己的类:

  • To compare two objects of your class you will have to override equals()
  • To use it as a key in any Hash based Data structure you will have to override hashcode()(again, keeping immutability in mind)
  • 要比较类的两个对象,您必须覆盖 equals()
  • 要将其用作任何基于哈希的数据结构中的键,您必须覆盖hashcode()(再次,牢记不变性)

Remember that if two objects are equal(), then their hashcode()should be equal as well!

请记住,如果两个对象是equal(),那么它们也hashcode()应该相等!

回答by Niranjan Nayak

hashCode()-HashMap provides put(key, value) for storing and get(key) method for retrieving Values from HashMap. When put() method is used to store (Key, Value) pair, HashMap implementation calls hashcode on Key object to calculate a hash that is used to find a bucket where Entry object will be stored. When get() method is used to retrieve value, again key object is used to calculate a hash which is used then to find a bucket where that particular key is stored.

hashCode()-HashMap 提供用于存储的 put(key, value) 和用于从 HashMap 检索值的 get(key) 方法。当 put() 方法用于存储 (Key, Value) 对时,HashMap 实现会调用 Key 对象上的 hashcode 来计算用于查找存储 Entry 对象的存储桶的哈希值。当 get() 方法用于检索值时,再次使用键对象来计算哈希,然后使用该哈希来查找存储该特定键的存储桶。

equals()- equals() method is used to compare objects for equality. In case of HashMap key object is used for comparison, also using equals() method Map knows how to handle hashing collision (hashing collision means more than one key having the same hash value, thus assigned to the same bucket. In that case objects are stored in a linked list, refer figure for more clarity. Where hashCode method helps in finding the bucket where that key is stored, equals method helps in finding the right key as there may be more than one key-value pair stored in a single bucket.

equals()- equals() 方法用于比较对象的相等性。如果使用 HashMap 键对象进行比较,同样使用 equals() 方法 Map 知道如何处理哈希冲突(哈希冲突意味着多个键具有相同的哈希值,因此分配到同一个桶。在这种情况下,对象是存储在链表中,请参阅图以获得更清晰的信息。其中 hashCode 方法有助于找到存储该键的存储桶,equals 方法有助于找到正确的键,因为单个存储桶中可能存储了多个键值对.

回答by Grzegorz Piwowarek

You can use any object in a HashMapas long as it has properly defined hashCodeand equalsmethods - those are absolutely crucial because the hashing mechanism depends on them.

您可以在 a 中使用任何对象,HashMap只要它已正确定义hashCodeequals方法 - 这些绝对至关重要,因为散列机制取决于它们。

回答by Nikhil

package com.java.demo.map;

import java.util.HashMap;

public class TestMutableKey
{
    public static void main(String[] args)
    {
        //Create a HashMap with mutable key
        HashMap<Account, String> map = new HashMap<Account, String>();

        //Create key 1
        Account a1 = new Account(1);
        a1.setHolderName("A_ONE");
        //Create key 2
        Account a2 = new Account(2);
        a2.setHolderName("A_TWO");

        //Put mutable key and value in map
        map.put(a1, a1.getHolderName());
        map.put(a2, a2.getHolderName());

        //Change the keys state so hash map should be calculated again
        a1.setHolderName("Defaulter");
        a2.setHolderName("Bankrupt");

        //Success !! We are able to get back the values
        System.out.println(map.get(a1)); //Prints A_ONE
        System.out.println(map.get(a2)); //Prints A_TWO

        //Try with newly created key with same account number
        Account a3 = new Account(1);
        a3.setHolderName("A_THREE");

        //Success !! We are still able to get back the value for account number 1
        System.out.println(map.get(a3)); //Prints A_ONE
    }
}

回答by Vaibhav Jain

Yes, you should override equals and hashcode, for the proper functioning of the code otherwise you won't be able to get the value of the key which you have inserted in the map.

是的,您应该覆盖 equals 和 hashcode,以便代码正常运行,否则您将无法获得已插入地图的键的值。

e.g

例如

map.put(new Object() , "value") ;

map.put(new Object() , "value") ;

when you want to get that value ,

当你想获得那个价值时,

map.get(new Object()) ; // This will always return null

map.get(new Object()) ; // 这将始终返回 null

Because with new Object() - new hashcode will be generated and it will not point to the expected bucket number on which value is saved, and if eventually bucket number comes to be same - it won't be able to match hashcode and even equals so it always return NULL .

因为使用 new Object() - 将生成新的哈希码并且它不会指向保存值的预期桶号,并且如果最终桶号变得相同 - 它将无法匹配哈希码甚至等于所以它总是返回 NULL 。