您现在的位置:首页 > 教案格式 > 正文

java 数组转字符串????回答主要是三个方面:(1)ha

2018-01-23 01:02 网络整理 教案网

java将字符串转为数组_java 数组转字符串_java string转字符串

????回答主要是三个方面:(1)hashmap的基本原理 (2)hashmap的put存源码解读 (3)hashmap的get取源码解读

??hashmap是基于hash算法的key-value键值对,通过key可以快速的找到value值,解决了数组的增加和删除以及链表的查询效率低的问题。

????Hashmap通过调用put函数,实现键值对的存储。

(1)为了保证key的唯一性,一般选用final修饰的类型,比如基本类型的引用类型、String。

????问:如果不用这些类型,别人把key都改了,取出来的值肯定就是错的啦

(2)获得hash值int hash =

hash(key);先得到key的hashcode值(因为每一个key的hashcode值都是唯一的),然后通过hash算法(底层是通过移位实现的),hash算法的目的就是让hashcode值能均匀的填充table表,而不是造成大量的集中冲突。

(3)将hash值与table数组的长度进行与运算,获得table数组下标int i = indexFor(hash,

table.length);

????问题:传统的方法是通过hashcode与table数组长度相除取余,这个使得table表中的数据分布不均匀,产生大量集中冲突。

(4)通过下标获得元素存储的位置,先判断该位置上有没有元素(hashmap定义的一个类entity,基本结构包含三个元素key、value和指向下一个entity的next),若不同的hash值算在同一个table下标下,这就产生了冲突。常用的冲突解决算法是:拉链法(采用头插法)、线性探测法。

(5)若不等,调用addEntry()将新创建一个元素添加到table中。创建元素entity时,要判断table的填充容量是否大于负载因子0.75,若大于就要扩容,容量扩充到两倍。

(6)扩容的时候,是在内存中开辟新的内存空间,然后把原来的对象放到新的table数组中,这个过程叫做重新散列(rehashing)。但是在多线程的时候,会出现条件竞争。比如两个线程发现hashmap需要重新调整大小,它们会同时试着调整大小。在调整大小的过程中,存储在链表中的元素的次序会反过来,因为移动到新的bucket位置的时候,HashMap并不会将元素放在链表的尾部,而是放在头部,这是为了避免尾部遍历(tail

traversing)。如果条件竞争发生了,那么就死循环了。

可以参考这篇文章:

(7)为了解决这个问题,采用了线程安全的CocurrentHashMap,它是行级锁,而hashtable是整体加锁。

????链接:

(1)直接定址法(或直接寻址法)

(2)数字分析法

(3)平方取中法(平方散列法)

????求index是一个非常频繁的操作,而乘法运算比除法来的省事(对CPU而言),所以把除法换成乘法和一个移位操作,公式: Index=(value*value)>>28(右移,是除以2^28. 记住:左移变大,是乘。右移变小,是除)

(4)折叠法

(5)除留余数法(这是最简单也是最常用的构造hash函数的方法)即对关键字取模Index=value%16(取模)

(6)随机数法

(1)开放定址法(线性探测再散列、二次探测再散列)(线性探测法)

(2)再哈希法(双散列函数法)

????在发生冲突的时候,再次使用另一个散列函数,计算哈希函数地址,直到冲突不再发生。

(3)链地址法(拉链法)(常用重点)

???? 就是一个数组+链表(链表采用头插法)

(4)建立一个公共溢出区。