本文由广州疯狂软件java培训分享:
从map说起吧,HashMap很经典了,自己的理解就是通过数组和链表实现的,hash算法最简单的理解就是取模,看源码可以知道HashMap内部有一个Entry[]的数组,而Entry本身的数据结构就是一个链表的节奏,差不多就是将key通过hash运算,在O(1)的时间里面确定要存在哪个Entry里面,就是等于确定Entry的下标,注意这里取的是key的hashCode()来进行计算,如果不重写hashCode(),则会默认调用父类Object的该方法,返回的是对象的内存地址。所以对于放入HashMap的对象一定要注意重写hashCode()方法,另外在存储的时候还会用到equals()方法所以务必同时重写hashCode()与equals()方法。贴个取值的代码
final Entry <k,v>getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
for (Entry 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;
}
这里又要说下关于重写的时候的注意事项了,我们对同一个对象总是希望产生同一个hashCode值,前面说了不重写则返回的是内存地址,而每一次new对象的地址都是不一样的,因此hashCode最好是根据对象的不易变的唯一属性计算得出。比如汽车我们可用车牌号来唯一标识等。
HashMap差不多弄懂后,其他Map也就没什么了,LinkedHashMap保留了键的插入顺序,数组+双向链表实现。TreeHashMap则可以根据键排序,因为可以排序,自然需要键实现Comparable接口,底层通过红黑树实现。
HashSet通过HashMap实现,因为HashMap的键不重复,就和Set没有重复元素这一点完美契合,不用岂不浪费~ HashTable很重要的一个特性就是他是线程安全的,因此在实现的时候,方法基本都会加上synchronized关键字,自然这也会造成效率上的一定损失。另外一个线程安全的类是Vector向量。
疯狂软件教育中心依托开发团队的强大技术实力,把企业最新技术融入实训课程,打造金牌的品质,才能给予学员黄金的未来,疯狂软件凭借过硬的技术实力与丰富的项目开发经验,赢得了社会的肯定。疯狂软件Java培训师资力量强大,课程内容深入,为学员高薪就业做了很好的铺垫,拥有丰富就业指导经验的就业团队也成为了学员高薪就业的先天优势。地址:广州天河区车陂沣宏大厦3楼。