【Java】HashMap

1.Map.Entry与HashMap.Node类,Node里面有一个next方法,我们可以认为一开始的时候HashMap的存储是按照链表存储的。

static class Node<K,V> implements Map.Entrhy<K,V>{}

在HashMap存储数据增加到一定数量的时候(阈值),那么就会由链表变为红黑树(性能更快)


2.阈值,超过这个值就会变为红黑树

static final int TREEIFY_THRESHOLD = 8 

3.HashMap里面对于数据的保存个数哥扩充是按照倍数进行的,但是这里面有一个参考百分比:

static final float DEFAULT_LOAD_FACTOR = 0.75f

.如果达到了16*0.75个数的时候会进行第一次容量扩充,而后16会变成32


5.HahsMap里面的方法都是异步处理的,属于非线程安全的,如果是读没有问题,如果是边读边写的话就会报出:java.util.CocurrentModificationException,表示的就是你存储的个数和你操作的个数不同。

比如运行下面这个代码,就会出错。

HashMap<int,int> map = new HashMap<int,int>();
for (int x =0;x<10;x++){
    new Thread(()->{
        for(int y =0;y<3;y++){
            map.put(Thread.currentThread().getName(),"y="+y);
            //但是如果边读边写
            System.out.println(map);
        }
    }).start();
}

6.HashMap中 Hash冲突时会影响HashMap性能,如何解决。

  在整个Hash存储过程中,必须要明确俩个问题,hashCode()和equal()方法。如果hashCode()相同,这个时候会查询equals(),不过一般在使用Map的时候都会考虑使用String来实现,所以在String实现的Key里面是不存在这种复杂的概念,也就是说这样的概念只存在于自定义类里面,所以当Hash冲突严重的时候,首先去考虑从euqals()方法是否正常,那么在进行数据定位的时候会更加的快速。

  但是如果从实际的数据结构的算法来讲,那么真的有哈希冲突的时候就需要使用一些特定的处理方法“

  1.开放定址法:为一个哈希冲突求一个地址序列

  2.链地址法:将所有哈希冲突的内容保存在一个链表里面(HashMap的实现原理)

  3.再哈希法:重新做一个hash计算

 

猜你喜欢

转载自www.cnblogs.com/guangluwutu/p/12305806.html