HashMap继承自抽象类AbstractMap,抽象类AbstractMap实现了Map接口。关系图如下所示:
import java.util.*;
public class SimpleMap extends AbstractMap {
//keys存储所有的键
private List keys = new ArrayList();
//values存储所有的值
private List values = new ArrayList();
/**
* 该方法获取Map中所有的键值对
*/
@Override
public Set entrySet() {
Set> set = new SimpleSet>();
//keys的size和values的size应该一直是一样大的
Iterator keyIterator = keys.iterator();
Iterator valueIterator = values.iterator();
while(keyIterator.hasNext() && valueIterator.hasNext()){
K key = keyIterator.next();
V value = valueIterator.next();
SimpleEntry entry = new SimpleEntry(key, value);
set.add(entry);
}
return set;
}
@Override
public V put(K key, V value) {
V oldValue = null;
int index = this.keys.indexOf(key);
if(index >= 0){
//keys中已经存在键key,更新key对应的value
oldValue = this.values.get(index);
this.values.set(index, value);
}else{
//keys中不存在键key,将key和value作为键值对添加进去
this.keys.add(key);
this.values.add(value);
}
return oldValue;
}
@Override
public V get(Object key) {
V value = null;
int index = this.keys.indexOf(key);
if(index >= 0){
value = this.values.get(index);
}
return value;
}
@Override
public V remove(Object key) {
V oldValue = null;
int index = this.keys.indexOf(key);
if(index >= 0){
oldValue = this.values.get(index);
this.keys.remove(index);
this.values.remove(index);
}
return oldValue;
}
@Override
public void clear() {
this.keys.clear();
this.values.clear();
}
@Override
public Set keySet() {
Set set = new SimpleSet();
Iterator keyIterator = this.keys.iterator();
while(keyIterator.hasNext()){
set.add(keyIterator.next());
}
return set;
}
@Override
public int size() {
return this.keys.size();
}
@Override
public boolean containsValue(Object value) {
return this.values.contains(value);
}
@Override
public boolean containsKey(Object key) {
return this.keys.contains(key);
}
@Override
public Collection values() {
return this.values();
}
}
public Collection values() {
if (values == null) {
values = new AbstractCollection() {
public Iterator iterator() {
return new Iterator() {
private Iterator> i = entrySet().iterator();
public boolean hasNext() {
return i.hasNext();
}
public V next() {
return i.next().getValue();
}
public void remove() {
i.remove();
}
};
}
public int size() {
return AbstractMap.this.size();
}
public boolean isEmpty() {
return AbstractMap.this.isEmpty();
}
public void clear() {
AbstractMap.this.clear();
}
public boolean contains(Object v) {
return AbstractMap.this.containsValue(v);
}
};
}
return values;
}
以下是我们自己实现的键值对类SimpleEntry,实现了Map.Entry
import java.util.Map;
//Map中存储的键值对,键值对需要实现Map.Entry这个接口
public class SimpleEntry implements Map.Entry{
private K key = null;//键
private V value = null;//值
public SimpleEntry(K k, V v){
this.key = k;
this.value = v;
}
@Override
public K getKey() {
return this.key;
}
@Override
public V getValue() {
return this.value;
}
@Override
public V setValue(V v) {
V oldValue = this.value;
this.value = v;
return oldValue;
}
}
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Iterator;
public class SimpleSet extends AbstractSet {
private ArrayList list = new ArrayList();
@Override
public Iterator iterator() {
return this.list.iterator();
}
@Override
public int size() {
return this.list.size();
}
@Override
public boolean contains(Object o) {
return this.list.contains(o);
}
@Override
public boolean add(E e) {
boolean isChanged = false;
if(!this.list.contains(e)){
this.list.add(e);
isChanged = true;
}
return isChanged;
}
@Override
public boolean remove(Object o) {
return this.list.remove(o);
}
@Override
public void clear() {
this.list.clear();
}
}
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
public class Test {
public static void main(String[] args) {
//测试SimpleMap的正确性
SimpleMap map = new SimpleMap();
map.put("iSpring", "27");
System.out.println(map);
System.out.println(map.get("iSpring"));
System.out.println("-----------------------------");
map.put("iSpring", "28");
System.out.println(map);
System.out.println(map.get("iSpring"));
System.out.println("-----------------------------");
map.remove("iSpring");
System.out.println(map);
System.out.println(map.get("iSpring"));
System.out.println("-----------------------------");
//测试性能如何
testPerformance(map);
}
public static void testPerformance(Map map){
map.clear();
for(int i = 0; i < 10000; i++){
String key = "key" + i;
String value = "value" + i;
map.put(key, value);
}
long startTime = System.currentTimeMillis();
for(int i = 0; i < 10000; i++){
String key = "key" + i;
map.get(key);
}
long endTime = System.currentTimeMillis();
long time = endTime - startTime;
System.out.println("遍历时间:" + time + "毫秒");
}
}
//创建HashMap的实例
HashMap map = new HashMap();
//测试性能如何
testPerformance(map);
@Override
public V put(K key, V value) {
V oldValue = null;
int index = this.keys.indexOf(key);
if(index >= 0){
//keys中已经存在键key,更新key对应的value
oldValue = this.values.get(index);
this.values.set(index, value);
}else{
//keys中不存在键key,将key和value作为键值对添加进去
this.keys.add(key);
this.values.add(value);
}
return oldValue;
}
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry 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;
}
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
import java.util.HashMap;
public class Car {
private final String num;//车牌号
public Car(String n){
this.num = n;
}
public String getNum(){
return this.num;
}
@Override
public boolean equals(Object obj) {
if(obj == null){
return false;
}
if(obj instanceof Car){
Car car = (Car)obj;
return this.num.equals(car.num);
}
return false;
}
public static void main(String[] args){
HashMap map = new HashMap();
String num = "鲁E.DE829";
Car car1 = new Car(num);
Car car2 = new Car(num);
System.out.println("Car1 hash code: " + car1.hashCode());
System.out.println("Car2 hash code: " + car2.hashCode());
System.out.println("Car1 equals Car2: " + car1.equals(car2));
map.put(car1, new String("Car1"));
map.put(car2, new String("Car2"));
System.out.println("map.size(): " + map.size());
}
}
我们在main函数中写了一些测试代码,我们创建了一个HashMap,该HashMap的用Car作为键,用字符串作为值。我们用同一个字符串实例化了两个Car,分别为car1和car2,然后将这两个car都放入到HashMap中,输出结果如下:
@Override
public int hashCode() {
return this.num.hashCode();
}
重新运行main中的测试代码,输出结果如下: