java集合实现原理和应用场景

两大类:collection接口实现的set、list、queue。Map接口实现的。 

List:不唯一。

        ArrayList:

                原理:动态数组实现,和数组的差别就在动态两个字。面试比较多的是扩容逻辑。(逻辑有点像分页逻辑,要考虑两头)默认是10,按照原来的容量1.5倍进行扩容,如果不够,那就设置为需要的大小,如果大于最大INT整数,则设置最大值。

哪种循环最快:(总共有4种。和数据量有关系。一般情况用增强for循环或者迭代器都可以(不是随机索引for),还有java8推出的foreach+lambd,随着数据量越多越快,但是需要jvm预热,即第一次很慢,后续就很快)

新增删除查询效率:

      支持快速随机访问。(即可以通过索引快速访问元素。因为是数组实现的。)

新增和删除,涉及到扩容的情况,数组需要进行内存的复制,元素的移动,所以通常情况是效率不高。

【 另外关于删除和新增的效率问题,这里需要特别注意,就是在数组尾部添加数据时,如果不需要扩容,是非常快的,但是实际情况,扩容是动态的,所以才有了查询快和新增删除效率不高这种说法。】

                应用场景:想想数组的应用场景。数组可以包含对象。

        线程安全替代方案

        1、JUC框架中的 copyonwriteArrayList类代替。

        2、vector(淘汰,性能太低)

        3、Collections.syncronizedList.

        编程建议

        1、能预估到容量大小,并且容量会特别大的情况,那最好是初始化容量。原因是初始容量是10,当调用add方法时会不停的扩容,不停的创建新数组再复制,造成无形的新能损耗。

        Linkedlist: 

                原理:双向链表实现。删除只需要修改前后节点指针的引用即可。关键点是理解链表的数据结构特点。节点保存了前后节点的信息。空间占用更多。但是增加删除更加效率。

                应用场景:一般是当做队列或者栈的场景去使用。,一般不需要随机访问(即以下标直接访问),增删多的可以使用linkedlist(现实情况是你要增删的前提是需要查找)。

Queue: 队列。

fifo特性。(先进先出)

Map:

        HashMap:

                原理:数组+链表实现,键值对的哈希结构,

                key通过计算hashcode,可以实现快速查找。

                也可以实现快速插入和删除。这里不得不说数据经过hash处理后,变得更容易实现某些功能了。

                另外说说扩容,参照hashset.

                应用场景:存储键值对。但是没有顺序。

        线程安全:cocurrentHashMap.

        编码建议:同hashList。初始容量是16。

        LinkedHashMap:

                原理:同上。

                应用场景:保存数据的插入顺序。(可以通过设置访问属性,调整数据顺序)

        TreeMap:

                原理:红黑树实现,key有序的map集合。要理解treemap,需要了解红黑树。大概的功能就是实现排序,并且兼顾效率。

                应用场景:按照整数自然顺序进行排序。(可以直接实现比较器,有点类似treeSet)

Set:唯一。

        HashSet:

                原理:底层数据结构是hashMap,所有值存储在hashMap的key上 ,hashcode计算散列值,获取存储的位置,equals判断是否进行覆盖。原始容量2的n次幂(n=4)= 16。扩展因子0.75。即容量占用0.75的时候,就开始扩展。扩展到2的进一次幂(5)。

                应用场景:快速查找。因为获取散列值的计算是O(1)【当然相同hash值需要再查找,但是这种情况不多】。

        TreeSet:

                原理:底层也是hashMap,但是可以实现排序。

                应用场景:排序。

hashcode和equals.

hashmap和hashset中是根据传入数据的hashcode方法获取到hash值,并根据这个值计算出在数组中的位置。在hashmap中,如果两个hashcode相同,再比较equals,判断是否相同,不相同才算真正不相同。

另外一个问题:为啥重写equals要重写hashcode。理解这个问题需要思考现实中的需求。一般重写equals说明两个值是相等的,当把两个相等的值放到hashmap或者hashset中,我们肯定是希望值放入一个,但是如果没有重写hashcode,因为hashmap和set的规则是根据hashcode来判断是否一致的,所以为了语义的统一,重写equals方法都要重写hashcode。

有了上述限定后,可以得到这样的关系。equals相等,hashcode必定相等。hashcode相等,equals不一定相等。hashcode不相等,equals必定不相等。equlas不相等,hashcode必定不相等。

总结起来就是:equals可以决定hashcode(是否相等),hashcode决定不了equals. 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值