Java各种集合总结

作为一个java小白,某天看代码的时候想起来前一天写代码遇到的问题,就是不太清楚java集合的特点,导致走了很多弯路。现在总结一下各自的特点:简单分为List、Set和Map,

List集合:(元素可重复)

1、ArrayList(最常用)
    底层数据结构是动态数组,优点:查询快、增删慢;缺点:效率高、线程不安全。
默认情况下,扩容为原来的1.5倍,同时需要将原有数组中的数据复制到新的数组中。
1.7:new ArrayList()的时候,底层object[] elementData初始化长度为10;
1.8:new ArrayList()的时候,底层object[] elementData初始化为{},并没有创建长度为10的数组,第一个调用add()时,底层才会创建长度10的数组。

小结:jdk1.7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk1.8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。

2、LinkedList
    底层数据结构是双向链表,优点:查询慢、增删快;缺点:效率高、线程不安全。

3、Vector(不常用)
    JDK1.0就出现了,线程安全的,所以效率低;如果不需要线程安全的实现,
建议使用ArrayList代替Vector。jdk7和jdk8通过Vector()构造器创建对象时,

Set集合:(元素不可重复)

Set集合最常用的就是HashSet和TreeSet。

以HashSet为例:

1、HashSet

1、无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值。
2、不可重复性:保证添加的元素按照equals()判断时,不能返回true,即:相同的元素只能添加一个

有两个重要的方法:hashCode()和equals()方法。如果你用的是自定义的实体类,需要重写该方法,不然还会存在重复数据。

添加元素的过程:以HashSet为例:
    我们向HashSet中添加元素a,首先调用元素a所在类的hashcode()方法,计算a的哈希值,此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断数组此位置上是否已经有元素:
    如果此位置上没有其他元素,则元素a添加成功。---->情况1
    如果次位置上有其他元素b(或以链表的形式存在多个元素),则比较元素a与b的hash值:
        如果hash值不相同,则元素添加成功。---->情况2
        如果hash值相同,进而需要调用元素a所在类的equals()方法:
            如果equals()返回false,则元素添加成功。---->情况3
            如果equals()返回true,则元素添加失败。

对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上的数据以链表形式存储
jdk7:元素a放到数组中,指向原来的元素,
jdk8:原来的元素在数组中,指向元素a。
总结:七上八下

HashSet底层:数组+链表

2、TreeSet

他的底层的数据结构是红黑树,有序的

可以按自己的需要重写比较器进行比较。

Map集合:键值对(一个键对应一个value)

1、HashMap

|---Map:双列数据,存储key-value数据
    |---HashMap:作为Map的主要实现类:线程不安全的,效率高;可以存储null的key和value。
        |---LinkHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历。
                原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素。
                对于频繁的遍历操作,此类执行效率高于HashMap。  
    |---TreeMap:保证按照添加的key-value进行排序,实现排序遍历。此时考虑key的自然排序或定制排序
                 底层使用红黑树。
    |---Hashtable:作为古老的实现类;线程安全的,效率低;不能存储null的key和value。
        |---Properties:常用来处理配置文件,key-value都是String类型。



HashMap底层:数组+链表  (jdk7及之前)
            数组+链表+红黑树   (jdk8)

二、Map结构的理解:
    Map中的key:无序的、不可重复的,使用Set存储所有的key。-->key所在的类要重写hashCode()和equals()方法。(以HashMap为例)
    Map中的value:无序的、可重复的,使用Collection存储所有的value。
    一个键值对:key-value构成了一个Entry对象。
    Map中的entry:无序的、不可重复的,使用Set存储所有的entry。

在不断添加过程中,会涉及到扩容问题,当超出临界值(容量*加载因子(0.75))时,且当前要添加的元素所在位置不为空时,扩容为原来的2倍;当放到新的数组中时,需要将所有的数据重新计算在新数组中的位置。
譬如:现在容量默认是16,临界值=16*0.75=12。

2、TreeMap

底层数据结构是红黑树,不允许null值和 null 键。线程安全

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值