标签:
HashMap的实现
-
package java.util;
-
import java.io.*;
-
-
public class HashMap<K,V>
-
extends AbstractMap<K,V>
-
implements Map<K,V>, Cloneable, Serializable
-
{
-
-
-
static final int DEFAULT_INITIAL_CAPACITY = 16;
-
-
-
static final int MAXIMUM_CAPACITY = 1 << 30;
-
-
-
static final float DEFAULT_LOAD_FACTOR = 0.75f;
-
-
-
transient Entry[] table;
-
-
-
transient int size;
-
-
-
int threshold;
-
-
-
final float loadFactor;
-
-
-
transient volatile int modCount;
-
-
-
public HashMap(int initialCapacity, float loadFactor) {
-
-
if (initialCapacity < 0)
-
throw new IllegalArgumentException("Illegal initial capacity: " +
-
initialCapacity);
-
-
if (initialCapacity > MAXIMUM_CAPACITY)
-
initialCapacity = MAXIMUM_CAPACITY;
-
-
if (loadFactor <= 0 || Float.isNaN(loadFactor))
-
throw new IllegalArgumentException("Illegal load factor: " +
-
loadFactor);
-
-
-
int capacity = 1;
-
while (capacity < initialCapacity)
-
capacity <<= 1;
-
-
-
this.loadFactor = loadFactor;
-
-
threshold = (int)(capacity * loadFactor);
-
-
table = new Entry[capacity];
-
-
init();
-
}
-
-
-
public HashMap(int initialCapacity) {
-
this(initialCapacity, DEFAULT_LOAD_FACTOR);
-
}
-
-
-
public HashMap() {
-
this.loadFactor = DEFAULT_LOAD_FACTOR;
-
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
-
table = new Entry[DEFAULT_INITIAL_CAPACITY];
-
init();
-
}
-
-
-
public HashMap(Map<? extends K, ? extends V> m) {
-
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
-
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
-
putAllForCreate(m);
-
}
-
-
-
-
-
void init() {
-
}
-
-
-
static int hash(int h) {
-
h ^= (h >>> 20) ^ (h >>> 12);
-
return h ^ (h >>> 7) ^ (h >>> 4);
-
}
-
-
-
static int indexFor(int h, int length) {
-
-
-
-
-
-
-
-
-
-
-
-
-
return h & (length-1);
-
}
-
-
-
public int size() {
-
return size;
-
}
-
-
-
public boolean isEmpty() {
-
return size == 0;
-
}
-
-
-
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;
-
}
-
-
-
private V getForNullKey() {
-
-
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
-
-
if (e.key == null)
-
return e.value;
-
}
-
-
return null;
-
}
-
-
-
public boolean containsKey(Object key) {
-
return getEntry(key) != null;
-
}
-
-
-
final Entry<K,V> getEntry(Object key) {
-
-
int hash = (key == null) ? 0 : 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 != null && key.equals(k))))
-
return e;
-
}
-
-
return null;
-
}
-
-
-
-
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;
-
}
-
-
-
private V putForNullKey(V value) {
-
-
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
-
-
if (e.key == null) {
-
-
V oldValue = e.value;
-
e.value = value;
-
e.recordAccess(this);
-
-
return oldValue;
-
}
-
}
-
modCount++;
-
addEntry(0, null, value, 0);
-
return null;
-
}
-
-
-
private void putForCreate(K key, V value) {
-
-
int hash = (key == null) ? 0 : 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 != null && key.equals(k)))) {
-
e.value = value;
-
return;
-
}
-
}
-
-
-
createEntry(hash, key, value, i);
-
}
-
-
-
private void putAllForCreate(Map<? extends K, ? extends V> m) {
-
for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) {
-
Map.Entry<? extends K, ? extends V> e = i.next();
-
putForCreate(e.getKey(), e.getValue());
-
}
-
}
-
-
-
void resize(int newCapacity) {
-
-
Entry[] oldTable = table;
-
-
int oldCapacity = oldTable.length;
-
-
if (oldCapacity == MAXIMUM_CAPACITY) {
-
threshold = Integer.MAX_VALUE;
-
return;
-
}
-
-
-
Entry[] newTable = new Entry[newCapacity];
-
-
transfer(newTable);
-
-
table = newTable;
-
-
threshold = (int)(newCapacity * loadFactor);
-
}
-
-
-
void transfer(Entry[] newTable) {
-
-
Entry[] src = table;
-
-
int newCapacity = newTable.length;
-
-
for (int j = 0; j < src.length; j++) {
-
-
Entry<K,V> e = src[j];
-
-
if (e != null) {
-
-
src[j] = null;
-
-
do {
-
-
Entry<K,V> next = e.next;
-
-
int i = indexFor(e.hash, newCapacity);
-
-
e.next = newTable[i];
-
-
newTable[i] = e;
-
-
e = next;
-
} while (e != null);
-
}
-
}
-
}
-
-
-
public void putAll(Map<? extends K, ? extends V> m) {
-
-
int numKeysToBeAdded = m.size();
-
if (numKeysToBeAdded == 0)
-
return;
-
-
-
if (numKeysToBeAdded > threshold) {
-
-
int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);
-
if (targetCapacity > MAXIMUM_CAPACITY)
-
targetCapacity = MAXIMUM_CAPACITY;
-
int newCapacity = table.length;
-
while (newCapacity < targetCapacity)
-
newCapacity <<= 1;
-
if (newCapacity > table.length)
-
resize(newCapacity);
-
}
-
-
-
for (Iterator<? extends Map.Entry<? extends K, ? extends V>> i = m.entrySet().iterator(); i.hasNext(); ) {
-
Map.Entry<? extends K, ? extends V> e = i.next();
-
put(e.getKey(), e.getValue());
-
}
-
}
-
-
-
public V remove(Object key) {
-
Entry<K,V> e = removeEntryForKey(key);
-
return (e == null ? null : e.value);
-
}
-
-
-
final Entry<K,V> removeEntryForKey(Object key) {
-
int hash = (key == null) ? 0 : hash(key.hashCode());
-
int i = indexFor(hash, table.length);
-
-
Entry<K,V> prev = table[i];
-
Entry<K,V> e = prev;
-
-
-
while (e != null) {
-
Entry<K,V> next = e.next;
-
Object k;
-
-
if (e.hash == hash &&
-
((k = e.key) == key || (key != null && key.equals(k)))) {
-
modCount++;
-
-
size--;
-
-
if (prev == e)
-
-
table[i] = next;
-
else
-
-
prev.next = next;
-
e.recordRemoval(this);
-
return e;
-
}
-
prev = e;
-
e = next;
-
}
-
-
return e;
-
}
-
-
-
final Entry<K,V> removeMapping(Object o) {
-
-
if (!(o instanceof Map.Entry))
-
return null;
-
-
-
Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
-
-
Object key = entry.getKey();
-
-
int hash = (key == null) ? 0 : hash(key.hashCode());
-
-
int i = indexFor(hash, table.length);
-
Entry<K,V> prev = table[i];
-
Entry<K,V> e = prev;
-
-
-
while (e != null) {
-
Entry<K,V> next = e.next;
-
-
if (e.hash == hash && e.equals(entry)) {
-
modCount++;
-
size--;
-
if (prev == e)
-
table[i] = next;
-
else
-
prev.next = next;
-
e.recordRemoval(this);
-
return e;
-
}
-
prev = e;
-
e = next;
-
}
-
-
-
return e;
-
}
-
-
-
public void clear() {
-
modCount++;
-
Entry[] tab = table;
-
-
for (int i = 0; i < tab.length; i++)
-
tab[i] = null;
-
-
size = 0;
-
}
-
-
-
public boolean containsValue(Object value) {
-
-
if (value == null)
-
return containsNullValue();
-
-
Entry[] tab = table;
-
-
for (int i = 0; i < tab.length ; i++)
-
-
for (Entry e = tab[i] ; e != null ; e = e.next)
-
-
if (value.equals(e.value))
-
return true;
-
-
return false;
-
}
-
-
-
private boolean containsNullValue() {
-
Entry[] tab = table;
-
for (int i = 0; i < tab.length ; i++)
-
for (Entry e = tab[i] ; e != null ; e = e.next)
-
if (e.value == null)
-
return true;
-
return false;
-
}
-
-
-
public Object clone() {
-
HashMap<K,V> result = null;
-
try {
-
result = (HashMap<K,V>)super.clone();
-
} catch (CloneNotSupportedException e) {
-
-
}
-
result.table = new Entry[table.length];
-
result.entrySet = null;
-
result.modCount = 0;
-
result.size = 0;
-
result.init();
-
result.putAllForCreate(this);
-
-
return result;
-
}
-
-
-
static class Entry<K,V> implements Map.Entry<K,V> {
-
final K key;
-
V value;
-
Entry<K,V> next;
-
final int hash;
-
-
-
Entry(int h, K k, V v, Entry<K,V> n) {
-
value = v;
-
next = n;
-
key = k;
-
hash = h;
-
}
-
-
-
public final K getKey() {
-
return key;
-
}
-
-
-
public final V getValue() {
-
return value;
-
}
-
-
-
public final V setValue(V newValue) {
-
V oldValue = value;
-
value = newValue;
-
return oldValue;
-
}
-
-
-
public final boolean equals(Object o) {
-
-
if (!(o instanceof Map.Entry))
-
return false;
-
-
Map.Entry e = (Map.Entry)o;
-
-
Object k1 = getKey();
-
Object k2 = e.getKey();
-
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
-
Object v1 = getValue();
-
Object v2 = e.getValue();
-
if (v1 == v2 || (v1 != null && v1.equals(v2)))
-
return true;
-
}
-
-
return false;
-
}
-
-
-
public final int hashCode() {
-
return (key==null ? 0 : key.hashCode()) ^
-
(value==null ? 0 : value.hashCode());
-
}
-
-
-
public final String toString() {
-
return getKey() + "=" + getValue();
-
}
-
-
-
void recordAccess(HashMap<K,V> m) {
-
}
-
-
-
void recordRemoval(HashMap<K,V> m) {
-
}
-
}
-
-
-
void addEntry(int hash, K key, V value, int bucketIndex) {
-
-
Entry<K,V> e = table[bucketIndex];
-
-
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
-
-
if (size++ >= threshold)
-
-
resize(2 * table.length);
-
}
-
-
-
void createEntry(int hash, K key, V value, int bucketIndex) {
-
Entry<K,V> e = table[bucketIndex];
-
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
-
size++;
-
}
-
-
-
private abstract class HashIterator<E> implements Iterator<E> {
-
Entry<K,V> next;
-
int expectedModCount;
-
int index;
-
Entry<K,V> current;
-
-
-
HashIterator() {
-
-
expectedModCount = modCount;
-
-
if (size > 0) {
-
Entry[] t = table;
-
while (index < t.length && (next = t[index++]) == null)
-
;
-
}
-
}
-
-
-
public final boolean hasNext() {
-
return next != null;
-
}
-
-
-
final Entry<K,V> nextEntry() {
-
-
if (modCount != expectedModCount)
-
throw new ConcurrentModificationException();
-
-
Entry<K,V> e = next;
-
-
if (e == null)
-
throw new NoSuchElementException();
-
-
-
if ((next = e.next) == null) {
-
Entry[] t = table;
-
while (index < t.length && (next = t[index++]) == null)
-
;
-
}
-
-
current = e;
-
-
return e;
-
}
-
-
-
public void remove() {
-
-
if (current == null)
-
throw new IllegalStateException();
-
-
if (modCount != expectedModCount)
-
throw new ConcurrentModificationException();
-
-
Object k = current.key;
-
-
current = null;
-
-
HashMap.this.removeEntryForKey(k);
-
-
expectedModCount = modCount;
-
}
-
-
}
-
-
-
private final class ValueIterator extends HashIterator<V> {
-
public V next() {
-
return nextEntry().value;
-
}
-
}
-
-
-
private final class KeyIterator extends HashIterator<K> {
-
public K next() {
-
return nextEntry().getKey();
-
}
-
}
-
-
-
private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
-
public Map.Entry<K,V> next() {
-
return nextEntry();
-
}
-
}
-
-
-
Iterator<K> newKeyIterator() {
-
return new KeyIterator();
-
}
-
Iterator<V> newValueIterator() {
-
return new ValueIterator();
-
}
-
Iterator<Map.Entry<K,V>> newEntryIterator() {
-
return new EntryIterator();
-
}
-
-
private transient Set<Map.Entry<K,V>> entrySet = null;
-
-
-
-
-
-
-
-
-
-
public Set<K> keySet() {
-
Set<K> ks = keySet;
-
-
return (ks != null ? ks : (keySet = new KeySet()));
-
}
-
-
-
private final class KeySet extends AbstractSet<K> {
-
-
public Iterator<K> iterator() {
-
return newKeyIterator();
-
}
-
-
public int size() {
-
return size;
-
}
-
-
public boolean contains(Object o) {
-
return containsKey(o);
-
}
-
-
public boolean remove(Object o) {
-
return HashMap.this.removeEntryForKey(o) != null;
-
}
-
-
public void clear() {
-
HashMap.this.clear();
-
}
-
}
-
-
-
-
-
-
-
-
-
-
public Collection<V> values() {
-
Collection<V> vs = values;
-
return (vs != null ? vs : (values = new Values()));
-
}
-
-
-
private final class Values extends AbstractCollection<V> {
-
public Iterator<V> iterator() {
-
return newValueIterator();
-
}
-
public int size() {
-
return size;
-
}
-
public boolean contains(Object o) {
-
return containsValue(o);
-
}
-
public void clear() {
-
HashMap.this.clear();
-
}
-
}
-
-
-
-
-
-
-
-
-
-
-
public Set<Map.Entry<K,V>> entrySet() {
-
return entrySet0();
-
}
-
-
private Set<Map.Entry<K,V>> entrySet0() {
-
Set<Map.Entry<K,V>> es = entrySet;
-
return es != null ? es : (entrySet = new EntrySet());
-
}
-
-
-
private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
-
public Iterator<Map.Entry<K,V>> iterator() {
-
return newEntryIterator();
-
}
-
public boolean contains(Object o) {
-
if (!(o instanceof Map.Entry))
-
return false;
-
Map.Entry<K,V> e = (Map.Entry<K,V>) o;
-
Entry<K,V> candidate = getEntry(e.getKey());
-
return candidate != null && candidate.equals(e);
-
}
-
public boolean remove(Object o) {
-
return removeMapping(o) != null;
-
}
-
public int size() {
-
return size;
-
}
-
public void clear() {
-
HashMap.this.clear();
-
}
-
}
-
-
-
private void writeObject(java.io.ObjectOutputStream s)
-
throws IOException
-
{
-
Iterator<Map.Entry<K,V>> i =
-
(size > 0) ? entrySet0().iterator() : null;
-
-
s.defaultWriteObject();
-
-
s.writeInt(table.length);
-
-
s.writeInt(size);
-
-
if (i != null) {
-
while (i.hasNext()) {
-
Map.Entry<K,V> e = i.next();
-
s.writeObject(e.getKey());
-
s.writeObject(e.getValue());
-
}
-
}
-
}
-
-
private static final long serialVersionUID = 362498820763181265L;
-
-
-
private void readObject(java.io.ObjectInputStream s)
-
throws IOException, ClassNotFoundException
-
{
-
s.defaultReadObject();
-
-
int numBuckets = s.readInt();
-
table = new Entry[numBuckets];
-
-
init();
-
-
int size = s.readInt();
-
-
for (int i=0; i<size; i++) {
-
K key = (K) s.readObject();
-
V value = (V) s.readObject();
-
putForCreate(key, value);
-
}
-
}
-
-
int capacity() { return table.length; }
-
float loadFactor() { return loadFactor; }
-
}
redis的两种模式
Redis 是一个高性能的key-value数据库。
redis的出现,很大程度补偿了memcached这类key-value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。
1. 按照我们一般的使用Redis的场景应该是这样的:
也就是说:我们会先去redis中判断数据是否存在,如果存在,则直接返回缓存好的数据。而如果不存在的话,就会去数据库中,读取数据,并把数据缓存到Redis中。
适用场合:如果数据量比较大,但不是经常更新的情况(比如用户排行)
2. 而第二种Redis的使用,跟第一种的情况完成不同,具体的情况请看:
这里我们会先去redis中判断数据是否存在,如果存在,则直接更新对应的数据(这一步会把对应更新过的key记录下来,比如也保存到redis中比如:key为:save_update_keys【用lpush列表记录】),并把更新后的数据返回给页面。而如果不存在的话,就会去先更新数据库中内容,然后把数据保存一份到Redis中。后面的工作:后台会有相关机制把Redis中的save_update_keys存储的key,分别读取出来,找到对应的数据,更新到DB中。
优点:这个流程的主要目的是把Redis当作数据库使用,更新获取数据比DB快。非常适合大数据量的频繁变动(比如微博)。
缺点:对Redis的依赖很大,要做好宕机时的数据保存。(不过可以使用redis的快照AOF,快速恢复的话,应该不会有多大影响,因为就算Redis不工作了,也不会影响后续数据的处理。)
难点:在前期规划key的格式,存储类型很重要,因为这会影响能否把数据同步到DB。
tcp消息相串如何处理
http://blog.csdn.net/pi9nc/article/details/17165171
java面试题
标签:
原文地址:http://blog.csdn.net/wenzhong003/article/details/51335381