哈希映射与类对象

huangapple go评论66阅读模式
英文:

Hashmap with class objects

问题

I have a Test class and its objects with same value (101,"abc") is created twice. I am inserting these two objects in a HashMap as a Key. I want to understand the internal functioning as to why I am getting a size of two for the map when both of my keys are the same; it should probably overwrite?

import java.util.HashMap;
import java.util.Map;

public class Test {
    int id;
    String name;

    public static void main(String[] args) {
        Test e1 = new Test(101, "abc");
        Test e2 = new Test(101, "abc");
        Map<Test, String> map = new HashMap<>();
        map.put(e1, "XYZ");
        map.put(e2, "CDF");
        String value = map.get(e2);
        System.out.println("VALUE: " + value);
    }

    public Test(int id, String name) {
        this.id = id;
        this.name = name;
    }
}
英文:

I have a Test class and its objects with same value (101,"abc") is created twice. I am inserting these two object in Hashmap as a Key. I want to understand the internal functioning as to why I am getting size as two of a map when both of my keys are same, it should probably overwrite ?

import java.util.HashMap;
import java.util.Map;
public class Test{
int id;
String name;
public static void main(String[] args) {
Test e1 = new Test(101,&quot;abc&quot;);
Test e2 = new Test(101,&quot;abc&quot;);
//Test e3 = new Test(101,&quot;abc&quot;);
Map&lt;Test, String&gt; map = new HashMap&lt;&gt;();
map.put(e1, &quot;XYZ&quot;);
map.put(e2, &quot;CDF&quot;);
String value = map.get(e2);
System.out.println( &quot;VALUE : &quot;+value);
}
public Test(int id, String name) {
this.id = id;
this.name=name;
}}

答案1

得分: 1

Test e1 = new Test(101,"abc");
Test e2 = new Test(101,"abc");

创建了两个不同类型为 Test 的对象。这意味着为 e1 和 e2 分别分配了两个不同的内存空间。

现在让我们来理解一下 map(比如哈希映射)如何识别键的唯一性(更简单地说,map 如何知道您要插入的键是否已经存在)。答案是,map 调用 hashcode() 和 equals() 方法来比较地图中已经存在的键与您要插入的键。

正如我们已经知道的,所有类都有一个默认的父类 Object。而 Test 类没有 hashcode() 和 equals() 方法的实现;因此,当 map 尝试调用它们时,会调用 object 类的方法。
由于 Object 类的 equals() 只有在比较中的两个对象引用同一个对象时才返回 true;hashcode() 也是如此,而在这里 e1 和 e2 显然是不同的对象。因此,您得到了两个条目。

解决方案是根据 @Kapil 的建议覆盖 equals() 和 hashcode()。


<details>
<summary>英文:</summary>

Test e1 = new Test(101,"abc");
Test e2 = new Test(101,"abc");

Creates 2 different objects of type **Test**. This means 2 different memory space has been allocated for e1 &amp; e2.

Now lets understand how does map( say Hash Map) identifies the uniqueness of key( in much simpler words, how does the map knows that the key you are trying to insert is already present or not). Answer is, map calls the hashcode() &amp; equals() method to compare the keys present in map with the one you are trying to insert.

As we already know all classes have a default parent class **Object** . And the **Test** class is not having an implementation of hashcode() &amp; equals(); so when map tried calling them, the object class method were called. 
As Object&#39;s class equals returns **true** only when both the objects in comparison refers to the same object reference &amp; so does the hashcode() and here e1 &amp; e2 are clearly different objects. So you got two entries.

Solution is to have an override the equals() &amp; hashcode() as suggested by @Kapil above.

</details>



# 答案2
**得分**: 0

除非你在Test类中重写hashcode()和equals()方法,否则哈希映射中将会有两个对象。如果你在Test类的id属性上重写这两个方法,那么具有相同id的两个键将被视为重复,你将看到预期的行为。

下面的示例说明了,如果它们的id相等,你想要使两个对象相等 -

```java
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + id;
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Test other = (Test) obj;
    if (id != other.id)
        return false;
    return true;
}
英文:

There will be two objects in the hashmap unless you override hashcode() and equals() methods in your Test class. If you override these two methods on the id property of Test class then the two keys with the same id would be treated as duplicate and you will see the expected behaviour.

Example below states that you want to make two object equals if their ids are equal -

@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + id;
			return result;
		}
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Test other = (Test) obj;
			if (id != other.id)
				return false;
			return true;
		}

huangapple
  • 本文由 发表于 2020年10月11日 16:32:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/64302041.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定