Hash表与树

jdk1.7中HashMap是由Hash表(即数组加链表)这种结构组成,而在jdk1.8后升级成了Hash表+红黑树用来提升数据的查询效率。下面将介绍hash表与红黑树。

Hash表

讲解hash表中我们先介绍线性检索二分搜索

线性检索

把所有数据遍历,找到你所需要的数据。其对应的数据结构就是数组、链表等线性结构,这种方式对于大数据而言效率极低,其时间复杂度为O(n)。比如ArrayList中的indexOf方法:

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}
二分搜索

二分搜索算是对线性搜索的一个改进,比如说对于【1,2,3,4,5,6,7,8】,我要搜索一个数(假设是2),我先将这个数与4(这个数一般选中位数比较好)比较,小于4则在4的左边【1,2,3】中查找,再与2比较,相等,就成功找到了,这种检索方式好处在于可以省去很多不必要的检索,每次只用查找集合中一半的元素。其时间复杂度为O(logn)。但其也有限制,他的数排列本身就需要是有序的

Hash表

好了,重点来了,Hash表闪亮登场,这是一种时间复杂度为O(1)的检索,就是说不管你数据有多少只需要查一次就可以找到目标数据。

Hash表的本质在于可以通过value本身的特征定位到查找集合的元素下标,从而快速查找。一般的Hash函数为:要存入的数 mod(求余) Hash数组长度。

看了上面的讲解,机智的你们肯定已经发现了一个问题,通过求余数得到的地址可能是一样的。这种我们称为Hash冲突,如果数据量比较大而Hash桶比较小,这种冲突就很严重。我们采取如下方式解决冲突问题。 我们可以看到12和0的位置冲突了,然后我们把该数组的每一个元素变成了一个链表头,冲突的元素放在了链表中,这样在找到对应的链表头之后会顺着链表找下去,至于为什么采用链表,是为了节省空间,链表在内存中并不是连续存储,所以我们可以更充分地使用内存。

红黑树

在JDK1.7中HashMap就采用了Hash表来存储数据,根据key计算出hashcode然后再与Hash数组长度求余得到Hash桶的位置。 如果很多的key产生了Hash冲突,那么每个桶里面的数据量比较大导致链表非常长,这样Hash表的优势就不复存在了,反而倾向于线性检索。 在jdk1.8版本后,java对HashMap做了改进,在链表长度大于8的时候,将后面的数据存在红黑树中,以加快检索速度,我们接下来讲一下红黑树。

转载于:https://my.oschina.net/qgmzzmn/blog/3102165

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值