Java集合类详解

1. 概述

Java是面向对象的语言,我们在编程的时候自然需要存储对象的容器,数组可以满足这个需求,但是数组初始化时长度是固定的,但是我们往往需要一个长度可变化的容器,因此,集合出现了.

Java集合框架图:
在这里插入图片描述
在这里插入图片描述

  1. Collection:Collection 是集合 List、Set、Queue 的最基本的接口。
  2. Iterator:迭代器,可以通过迭代器遍历集合中的数据
  3. Map:是映射表的基础接口
     
     

2. Collection接口

2.1 List接口

元素可以重复,通过.equals()方法判断元素重复;
是一个有序集合,读取顺序保持和插入时的顺序一致
 

2.1.1 ArrayList

结构:基于数组实现;默认初始容量为10,元素满时扩容,每次扩容50%

特点:线程不安全,随机访问效率快,插入删除慢

底层原理:数组结构是有序的元素序列,在内存中开辟一段连续的空间,在空间中存放元素,每个空间都有编号(即数组的每个元素的下标),通过编号可以快速找到相应元素,所以随机访问效率高;在中间插入删除元素时,需要把后面的元素的下标全部移动,并且当元素个数达到总长度时,会进行扩容,扩容会创建新数组并把原来的数据的数据迁移过去,所以插入删除效率慢
 

2.1.2 LinkedList

结构:基于双向链表实现;无初始容量,不会扩容

特点:线程不安全,随机访问效率慢,插入删除快

底层原理:双向链表没有长度的限定,所以无初始容量,没有所谓的扩容,每个元素前后都有一个指向其他元素的指针(头节点没有),在插入删除的时候只需将插入或删除的位置前后指针连接起来,所以增删效率快,随机访问的时候需要从头开始移动指针遍历,所以随机访问效率慢
 

2.1.3 Vector

结构:基于数组实现;默认初始容量为10,元素满时扩容,每次扩容100%

特点:线程安全

底层原理:底层实现和ArrayList一样,不同的是Vector的方法使用了sychornized关键字,所以线程安全,但是效率不及ArrayList,并且扩容时每次扩容为原来的2倍
 

2.2 Set接口

元素不可以重复,通过.equals()方法判断元素重复;
元素无序,不可通过元素下标来随机访问
 

2.2.1 HashSet

结构:哈希表(JDK1.7 数组+链表,JDK1.8 数组+链表+红黑树),JDK1.8当链表长度超过阈值(8)转换为红黑树,红黑树长度低于阈值(6)转换为链表

特点:线程不安全,无序且元素不可以重复,查询快

底层原理:HashSet可以看作是HashMap的key的集合,底层是创建一个HashMap集合,将元素存放于HasMap的key中,具体实现可以参考HashMap的底层原理
 

2.2.2 TreeSet

结构:红黑树

特点:线程不安全,元素不可以重复,插入比较元素进行排序(可以指定升序或降序),查询快

底层原理:TreeSet可以看作是TreeMap的key的集合,底层是创建一个TreeMap集合,将元素存放于TreeMap的key中,具体实现可以参考TreeMap的底层原理
 

2.2.3 LinkedHashSet

结构:哈希表(JDK1.7 数组+链表,JDK1.8 数组+链表+红黑树),JDK1.8当链表长度超过阈值(8)转换为红黑树,红黑树长度低于阈值(6)转换为链表

特点:线程不安全,元素不可以重复,插入比较元素进行排序(可以指定升序或降序),查询快

底层原理:TreeSet底层原理和HashSet一样,不同的是TreeSet的add方法使用二叉树的原理对新插入的元素通过比较元素值按照指定(默认升序,降序)顺序排序,每次add一个元素都会排序,所以它是有序的,比较元素值是调用元素对象的 compareTo()方法,所以插入的元素必须实现 Comparable接口并重写compareTo()方法才可以正常使用,并且在覆写 compare()函数时,要返回相应的值才能使 TreeSet 按照一定的规则来排序
 
 

3. Map接口

元素为key-value结构,key不可以重复,通过.equals()方法判断key是否重复;
是一个无序集合,但是随机访问效率高
 

3.1 HashMap

结构:哈希表(JDK1.7 数组+链表,JDK1.8 数组+链表+红黑树),JDK1.8当链表长度超过阈值(8)转换为红黑树,红黑树长度低于阈值(6)转换为链表,初始容量为16,当达到负载因子0.75f(key-value总量达到容量的0.75倍,注意是key-value的size,不是含有元素的node节点数)扩容,每次扩容为原来的两倍

特点:线程不安全,key和value可以为null,无序,随机查询快

底层原理:散列表数组即哈希表,每个位置是一个Entry(Map的内部接口,HashMap实现了它的子类命名为Node)节点,标记一个hash值,在put新元素时。先通过获取key的hashCode通过hash计算出hash值,根据hash值将元素放到数组指定的Entry上,若该Entry上已经有元素则调用.equals()判断是否存在相同的key,存在则覆盖原来的值,不存在则称为哈希冲突,用链表连接起来,JDK1.8当链表长度达到8(因为链表的复杂度的为O(n/2),红黑树复杂度为O(log2n),n=8为临界值,大于8则红黑树复杂度小于链表,所以阈值为8)转换为红黑树,移除元素时,当红黑树长度低于6时转换为链表;随机访问是通过计算key的hash值再到指定Entry上查找,所以随机访问效率很高;
 

3.1.1 LinkedHashMap

结构:与HashMap一致

特点:线程不安全,key和value可以为null,有序,随机查询快

底层原理:LinkedHashMap是HashMap的一个子类,它的Entery继承自HashMap的Node,根据双向链表的原理增加了before和after两个Entry,分别指向前一个插入的Entry(before)和后一个插入的Entry(after),在遍历的时候会按照插入的顺序遍历,所以它是有序的,它还提供了一个构造方法,在构造的时候带参数,按照指定的访问次序排序
 

3.2 HashTable

结构:哈希表(JDK1.7 数组+链表,JDK1.8 数组+链表+红黑树),JDK1.8当链表长度超过阈值(8)转换为红黑树,红黑树长度低于阈值(6)转换为链表,初始容量为11,当达到负载因子0.75f(key-value总量达到容量的0.75倍,注意是key-value的size,不是含有元素的node节点数)扩容,每次扩容为原来的2n+1

特点:线程安全,key和value都不可以为null

底层原理:HashTable底层实现原理和HashMap一样,不同的是HashTable的方法都使用synchronized关键字修饰,所以它是线程安全的,但是效率不及HashMap,并且key-value都不能为null,初始容量和扩容大小也和HashMap不同
 

3.3 TreeMap

结构:红黑树,无初始大小,没有扩容机制

特点:线程不安全,元素不可以重复,插入比较元素进行排序(可以指定升序或降序),查询快

底层原理:采用红黑树的数据结构,长度没限制,所以没有初始大小和扩容机制,红黑树的是一个高效平衡二叉树,并且总是左子节点小于父节点,右子节点大于父节点,所以插入时需要比较每个元素值,是一个有序集合,TreeMap提供了指定比较器的构造方法,若创建时没有指定比较器,则按照自然排序,自然排序需要所有的key实现Compareble接口并重写campareTo()方法才可以正常使用,若制定了比较器则按照比较器指定的方法比较元素值排序;红黑树的时间复杂度为O(log2N),随机访问效率高

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值