标签:java hashmap hashcode equals 哈希
HashMap继承自抽象类AbstractMap,抽象类AbstractMap实现了Map接口。关系图如下所示:
import java.util.*; public class SimpleMap<K,V> extends AbstractMap<K,V> { //keys存储所有的键 private List<K> keys = new ArrayList<K>(); //values存储所有的值 private List<V> values = new ArrayList<V>(); /** * 该方法获取Map中所有的键值对 */ @Override public Set entrySet() { Set<Map.Entry<K, V>> set = new SimpleSet<Map.Entry<K,V>>(); //keys的size和values的size应该一直是一样大的 Iterator<K> keyIterator = keys.iterator(); Iterator<V> valueIterator = values.iterator(); while(keyIterator.hasNext() && valueIterator.hasNext()){ K key = keyIterator.next(); V value = valueIterator.next(); SimpleEntry<K,V> entry = new SimpleEntry<K,V>(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<K> set = new SimpleSet<K>(); Iterator<K> 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<V> values() { if (values == null) { values = new AbstractCollection<V>() { public Iterator<V> iterator() { return new Iterator<V>() { private Iterator<Entry<K,V>> 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<K,V>接口,代码如下:
import java.util.Map; //Map中存储的键值对,键值对需要实现Map.Entry这个接口 public class SimpleEntry<K,V> implements Map.Entry<K, V>{ 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<E> extends AbstractSet<E> { private ArrayList<E> list = new ArrayList<E>(); @Override public Iterator<E> 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<String, String> map = new SimpleMap<String, String>(); 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<String, String> 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<String, String> map = new HashMap<String, String>(); //测试性能如何 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<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; }
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<K,V> 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<K,V> 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<Car, String> map = new HashMap<Car, String>(); 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中的测试代码,输出结果如下:
标签:java hashmap hashcode equals 哈希
原文地址:http://blog.csdn.net/iispring/article/details/46594725