Hashmap和LinkedHashmap的对比

java中很多数据容器都是基于数组实现的,hashmap和linkedhashmap也不例外,都是内部维护一个数组,但是数组存放的元素不是普通的对象,而是经过包装的对象。hashmap中的包装类如下
static class Entry<K,V> implements Map.Entry<K,V> {
    final K key;//存放进去的key
    V value;//存放的value
    Entry<K,V> next;//指向hash相同的下个元素
    int hash;
    .....}
hashmap在内存中是数组和链表的结合体,对于put方法,实现的步骤如下:通过哈希算法算出对应数组的下标(哈希算法的作用是将key的哈希值与数组长度len进行&运算得到一个len范围内的正整数),如果数组那个位置没有存放了元素,就存放在那个地方。如果存放了元素,那么这里就存在一个链表,可能这个链表只有一个记录,可能有两个,然后遍历这个链表,那么这个时候通过key来比较,如果key存在key相同的,就替换原来的value,否则就将新插入的键值对放在这个链表的首位,也就是数组上。
上面的叙述可以知道,随着元素增多,组成链表的可能性会大大增加,那么性能会大大降低。为了保证hashmap的性能,引入了两个变量:int threshold; 表示数组能存放多少个元素而不是数组的大小 
 final float loadFactor;threshold和数组大小的比率。默认是0.75
每次插入的时候都会进行threshold大小检查,如果size超过界限会进行扩容,元素会进行重新排列。这是十分影响性能的事情。所以尽量初始化一个合理的大小。
linkedhashmap是hashmap的子类,和hashmap不同的是,它是有序的,默认是按插入排序,而hashmap是无序的。实现这个的关键是继承了hashmap中的Map.Entry<K,V>,并且添加了两个元素
 private static class Entry<K,V> extends HashMap.Entry<K,V> {
    // These fields comprise the doubly linked list used for iteration.
    Entry<K,V> before, after;//
    ..}
before和after是关键。这是典型的双向链表数据结构,这两个引用会将map中所有的元素串起来,从而实现有序排列。linkedhashmap会在hashmap的,增删方法中多进行一些操作,那就是对这引用的维护。
    private void remove() {
        before.after = after;
        after.before = before;
    }
    private void addBefore(Entry<K,V> existingEntry) {
        after  = existingEntry;
        before = existingEntry.before;
        before.after = this;
        after.before = this;
    }
这两个方法是linkedhashmap自己实现的维护链表的操作。
linkedhashmap默认是按照插入排序的,它提供了两种排序方式,插入排序和访问排序,通过accessOrder这个布尔类型的成员变量控制。当实现访问排序的时候,那么就是一个LRU-1算法的实现。在一个大小固定容器,如果容器满了,添加的时候会将访问时间最久远的元素剔除。用linkedhashmap实现非常简单,只需要继承它,然后复写它的两个方法即可。
public class LRUOneQueue<K, V> extends LinkedHashMap<K, V> {
private int cacheSize ;

@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
    return size() > cacheSize;
}

public LRUOneQueue(int cacheSize){
    super();
    this.cacheSize=cacheSize;

}

}
这就完成完成一个简单的LRU-1算法数据结构。
最后,这两个数据结构都能自动扩容,但是不能自动缩小。而且使用集合类的时候要小心内存泄漏。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值