据我所知,这HashSet是基于HashMap实现,但在需要独特的元素集时使用.那么为什么在下一个代码中将相同的对象放入地图并设置时,我们将两个集合的大小等于1?地图大小不应该是2?因为如果两个集合的大小相等,我认为使用这两个集合没有任何区别.
Set testSet = new HashSet<SimpleObject>();
Map testMap = new HashMap<Integer, SimpleObject>();
SimpleObject simpleObject1 = new SimpleObject("Igor", 1);
SimpleObject simplObject2 = new SimpleObject("Igor", 1);
testSet.add(simpleObject1);
testSet.add(simplObject2);
Integer key = new Integer(10);
testMap.put(key, simpleObject1);
testMap.put(key, simplObject2);
System.out.println(testSet.size());
System.out.println(testMap.size());
Run Code Online (Sandbox Code Playgroud)
输出为1和1.
SimpleObject code
public class SimpleObject {
private String dataField1;
private int dataField2;
public SimpleObject(){}
public SimpleObject(String data1, int data2){
this.dataField1 = data1;
this.dataField2 = data2;
}
public String getDataField1() {
return dataField1;
}
public int getDataField2() {
return dataField2;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((dataField1 == null) ? 0 : dataField1.hashCode());
result = prime * result + dataField2;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SimpleObject other = (SimpleObject) obj;
if (dataField1 == null) {
if (other.dataField1 != null)
return false;
} else if (!dataField1.equals(other.dataField1))
return false;
if (dataField2 != other.dataField2)
return false;
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
Boz*_*zho 129
地图包含唯一键.使用put映射中存在的键调用时,该键下的对象将替换为新对象.因此大小为1.
两者之间的区别应该是显而易见的:
Map你存储键值对Set你只存储钥匙实际上,a HashSet有一个HashMap字段,无论何时add(obj)被调用,该put方法都在底层映射上调用map.put(obj, DUMMY)- 其中虚拟对象是a private static final Object DUMMY = new Object().因此,地图将填充您的对象作为键,以及一个不感兴趣的值.
在HashSet的情况下,添加相同的对象将或多或少是一个无操作.对于HashMap,将新键,值对与现有键放在一起将覆盖现有值,以便为该键设置新值.下面我给你的代码添加了equals()检查:
SimpleObject simpleObject1 = new SimpleObject("Igor", 1);
SimpleObject simplObject2 = new SimpleObject("Igor", 1);
//If the below prints true, the 2nd add will not add anything
System.out.println("Are the objects equal? " , (simpleObject1.equals(simpleObject2));
testSet.add(simpleObject1);
testSet.add(simplObject2);
Integer key = new Integer(10);
//This is a no-brainer as you've the exact same key, but lets keep it consistent
//If this returns true, the 2nd put will overwrite the 1st key-value pair.
testMap.put(key, simpleObject1);
testMap.put(key, simplObject2);
System.out.println("Are the keys equal? ", (key.equals(key));
System.out.println(testSet.size());
System.out.println(testMap.size());
Run Code Online (Sandbox Code Playgroud)