HashSet和HashMap之间有很多的相似之处。对于HashSet而言,系统采用Hash算法决定集合元素的存储位置,这样可以保证快速存、取集合元素;对于HashMap而言,系统将value当成key的“附属物”,系统根据Hash算法来决定key的存储位置,这样可以保证快速存、取集合的key,而value总是紧跟着key存储。
虽然集合号称存储的是java对象,但是实际上并不是真正的把Java对象放入集合中,而只是在集合中保留这些对象的引用而已。
下面将详细的介绍HashSet和HashMap对集合元素的存储方式。
HashMap<String,Double> map = new HashMap();
map.put("语文",80.0);
map.put("数学",89.0);
map.put("英语",78.2);
当程序执行map.put("语文","80.0")时,系统将调用“语文”的hashCode方法得到其hashCode值,系统再根据该值决定该元素的存储位置。
对应源码如下:
public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode());// 调用key的hashCode方法,获取其HashCode值 int i = indexFor(hash, table.length);//根据HashCode值决定该元素的存储位置 for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
对于HashSet而言,它是基于HashMap实现的。它只是封装了一个HashMap对象来存储所有的集合元素。所有放入到HashSet中的集合元素实际上由HashMap的key来保存,而value是一个静态的Object对象。
add()方法源码
public boolean add(E e) { return map.put(e, PRESENT)==null; }