集合

ArrayList
查询快, 底层是用的数组存储,而数组的查询实际上是对引用地址的访问,不需要遍历。
新增时:(1)往ArrayList中添加对象,也就是调用add(element)方法,首先会确认容量是否足够,如果足够,将新加入的元素直接放入,如果直接调用的add(element)方法,会从最后一个元素的末尾开始增加新的元素,如果是调用的add(index,element)方法,则直接从下标为index的位置开始插入新的元素E,该下标靠后位置(index+1)元素向右移一位。 
(2)ArrayList默认长度是10, 加载因子为0.5, 扩容增量是原容量的0.5倍+1, 如果容量不够,则需要先扩容,扩容结束后,调用了Arrays.copyOf(elementData, newCapacity)方法,这个方法中:对于我们这里而言,先创建了一个新的容量为newCapacity的对象数组,然后使用System.arraycopy()方法将旧的对象数组复制到新的对象数组中去了。扩容结束之后新增的操作和之前一样。
列如 new int arr[5];arr数组的地址假设为0x1000   arr[0] ~ arr[5] 地址可看作为 0x1000 + i * 4  首地址 + 下标 + 引用数据类型的字节大小
增删慢(使用数组的弊端)
ArrayList删除是调用的remove(index)方法,将下标为index位置之后的元素向前移动一个位置,最后的一个位置设为null,等待gc回收之后,集合的size()减少1。 
每当插入或删除操作时 对应的需要向前或向后的移动元素,当插入元素时 需要判定是否需要扩容操作
扩容操作:创建一个新数组 增加length 再将元素放入进去较为繁琐


LinkList
查询慢(双向链表的弊端)双向链表的查询逻辑是他会根据index的大小判断是从前开始遍历还是从后开始遍历,如果index更靠前就从前遍历,更靠后就从后遍历,也就是在查询过程中,会一次次的移动指针直到获取到index的值。增删快:只需要修改插入位置或删除位置左右数据的引用目标即可

LinkList比ArrayList更占内存, 因为LinkedList为每个节点存储了两个引用, 一个指向前一个元素, 一个指向下一个元素
 


 Set:
(1)HashSet底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。 具体实现唯一性的比较过程:存储元素首先会使用hash()算法函数生成一个int类型hashCode散列值,然后已经的所存储的元素的hashCode值比较,如果hashCode不相等,则所存储的两个对象一定不相等,此时存储当前的新的hashCode值处的元素对象;如果hashCode相等,存储元素的对象还是不一定相等,此时会调用equals()方法判断两个对象的内容是否相等,如果内容相等,那么就是同一个对象,无需存储;如果比较的内容不相等,那么就是不同的对象,就该存储了,此时就要采用哈希的解决地址冲突算法,在当前hashCode值处类似一个新的链表, 在同一个hashCode值的后面存储存储不同的对象,这样就保证了元素的唯一性。 Set的实现类的集合对象中不能够有重复元素,HashSet也一样他是使用了一种标识来确定元素的不重复,HashSet用一种算法来保证HashSet中的元素是不重复的, HashSet采用哈希算法,底层用数组存储数据。
TreeSet底层数据结构采用二叉树来实现,元素唯一且已经排好序;唯一性同样需要重写hashCode和equals()方法,二叉树结构保证了元素的有序性。根据构造方法不同,分为自然排序(无参构造)和比较器排序(有参构造),自然排序要求元素必须实现Compareable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储;比较器排需要在TreeSet初始化是时候传入一个实现Comparator接口的比较器对象,或者采用匿名内部类的方式new一个Comparator对象,重写里面的compare()方法;
 

集合的初始容量、加载因子、扩容增量
ArrayList扩容增量是原容量的0.5倍+1。(至于原理后面会解析源码)例如:ArrayList的初始容量是10,一次扩容后容量为16
Vector 加载因子是1,也就是说元素个数超过容量长度,进行扩容,扩容为原来的1倍。例如:Vector 初始容量为10,一次扩容后容量为20
HashSet线程不安全,存取速度快, 底层实现是一个HashMap(保存数据),实现Set接口 加载因子为0.75,也就是元素超过容量长度的0.75时,进行扩容。扩容为原来的1倍。(至于原理后面会解析源码)
例如:HashSet的初始容量为16,数据量达到12时,进行扩容,扩容后容量为32

Map是一个双列集合
HashMap线程不安全,加载因子是0.75。例如:HashMap的初始容量为16,数据量达到12时,进行扩容,扩容后容量为32
HashTable线程安全, 加载因子是0.75, 扩容增量:2*原数组长度+1, 例如:HashTable的初始容量为11,数据量达到9时,进行扩容,扩容后容量为23

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值