好久好久好久没有发博了,那是因为新公司确实很忙,一个比较大的互联网公司。。
言归正传。
这里主要简单记录一下红黑树,
1.7和1.7以前HashMap都是“数组+链表”实现的,1.8之后就是“数组+(链表或红黑树)”来实现了,HashMap底层依旧是个数组,然后数组中的元素是链表或者红黑树来实现。
那么HashMap是怎么使用红黑树的呢?
JDK1.7的时候是使用一个Entry数组来存储数据,用key的hashcode取模来决定key会被放到 数组里的哪个位置,如果hashcode相同,或者hashcode取模后的结果相同,那么这些key会被定位到Entry数组的同一个格子里,这个链表可能会很长,那么put、get操作都可能需要遍历这个链表,也就是说时间复杂度在最差情况下会是O(n)
红黑树它的好处是他的自平衡性,让他这棵树最大的高度为2log(n+1),n是树的节点数,那么红黑树的复杂度就只有O(log n);
下面是一个根据自己理解写的一个Hashmap的原理的代码,这里记录并分享给大家:
PS:可能写的不完整,主要是一些hash算法,put的方法的实现。没有用到红黑树呦
package Hashmap;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
public class HashmapUtils<K,V> implements Map<K,V> {
private Entry<K,V>[] table = null;
private static int defaultLength = 16; //默认数组长度
private static double defaultLoader = 0.75d; //需要扩容的加载因子
private int size = 1 ; //判断是否扩容的标准
public HashmapUtils(int length,double loader){
defaultLength = length;
defaultLoader = loader;
table=new Entry[defaultLength];
}
public HashmapUtils(){
this(defaultLength,defaultLoader);
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean containsKey(Object key) {
return false;
}
@Override
public boolean containsValue(Object value) {
return false;
}
@Override
public V get(Object key) {
Entry<K,V> entry = getEntry(key);
return null == entry ? null : entry.getValue();
}
private Entry<K,V> getEntry(Object key) {
if (size == 0){
return null;
}
int index = hash((K)key);
for (Entry e = table[index];e!=null;e=e.next){
if (e.hash==index && (key==e.getKey()||key.equals(e.getKey()))){
return e;
}
}
return null;
}
@Override
public V put(K key, V value) {
int index = hash(key);
Entry<K,V> entry = table[index];
if (null == entry){
table[index] = addEntry(index,key,value,null);
size++;
}else {
table[index] = addEntry(index,key,value,entry);
}
return table[index].getValue();
}
private Entry<K, V> addEntry(int hash, K key, V value, Entry next) {
return new Entry<>(key,value,next,hash);
}
@Override
public V remove(Object key) {
return null;
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
}
@Override
public void clear() {
}
@Override
public Set<K> keySet() {
return null;
}
@Override
public Collection<V> values() {
return null;
}
public int hash(K key){
int index = key.hashCode()%defaultLength-1;
return Math.abs(index);
}
@Override
public Set<Map.Entry<K, V>> entrySet() {
return null;
}
class Entry<K,V> implements Map.Entry{
K k;
V v;
Entry<K,V> next;
int hash;
public Entry(K k, V v, Entry<K, V> next, int hash) {
this.k = k;
this.v = v;
this.next = next;
this.hash = hash;
}
@Override
public K getKey() {
return k;
}
@Override
public V getValue() {
return v;
}
@Override
public Object setValue(Object value) {
return null;
}
}
}