集合

集合复习

作è€ï¼šZ-AI

说明:对于以上的框架图有如下几点说明

集合接口:6个接口(短虚线表示),表示不同集合类型,是集合框架的基础。
抽象类:5个抽象类(长虚线表示),对集合接口的部分实现。可扩展为自定义集合类。
实现类:8个实现类(实线表示),对接口的具体实现。
Collection 接口是一组允许重复的对象。 Set 接口继承 Collection,集合元素不重复。 List 接口继承
Collection,允许重复,维护元素插入顺序。 Map接口是键-值对象,与Collection接口没有什么关系。

List

元素是有序的、可重复

ArrayList、Vector默认初始容量为10

Vector:线程安全,但速度慢,底层数据结构是数组结构

​ 加载因子为1:即当 元素个数 超过 容量长度 时,进行扩容

扩容增量:原容量的 1倍

如 Vector的容量为10,一次扩容后是容量为20

ArrayList:线程不安全,查询速度快

底层数据结构是数组结构

扩容增量:原容量的 0.5倍+1

如 ArrayList的容量为10,一次扩容后是容量为16

ArrayList:
  1. ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长。
    ArrayList不是线程安全的,只能用在单线程环境下。
    实现了Serializable接口,因此它支持序列化,能够通过序列化传输;
    实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问;
    实现了Cloneable接口,能被克隆。
  2. remove方法会让下标到数组末尾的元素向前移动一个单位,并把最后一位的值置空,方便GC
  3. ArrayList是List接口的可变数组非同步实现,并允许包括null在内的所有元素。
  4. 该集合是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍,这种操作的代价很高。

LinkedList

​ LinkedList底层使用的双向链表结构,有一个头结点和一个尾结点,双向链表意味着我们可以从头开始正向遍历,或者是从尾开始逆向遍历,并且可以针对头部和尾部进行相应的操作。

Set

元素无序的、不可重复。

HashSet:
  1. 线程不安全,存取速度
  2. 底层实现是一个HashMap(保存数据),实现Set接口
  3. 默认初始容量为16(为何是16,见下方对HashMap的描述)
  4. 加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容
  5. 扩容增量:原容量的 1 倍
  6. 如 HashSet的容量为16,一次扩容后是容量为32
  7. HashSet底层是基于HashMap 或者 LinkedHashMap实现的,所以HashSet数据结构就是HashMap或者LinkedHashMap的数据结构

​ 说明:HashSet中由于只包含键,不包含值,由于在底层具体实现时,使用的HashMap或者是LinkedHashMap(可以指定构造函数来确定使用哪种结构),我们知道HashMap是键值对存储,所以为了适应HashMap存储, HashSet增加了一个PRESENT类域(类所有),所有的键都有同一个值(PRESENT)

Map

是一个双列集合

  1. 默认初始容量为16(为何是16:16是2^4,可以提高查询效率,另外,32=16<<1 -->至于详细的原因可另行分析,或分析源代码)
  2. 加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容
  3. 扩容增量:原容量的 1 倍,如 HashSet的容量为16,一次扩容后是容量为32
  4. Hashtable: 线程安全
  5. 加载因子为0.75:即当 元素个数 超过 容量长度的0.75倍 时,进行扩容
  6. HashMap是基于哈希表的Map接口的非同步实现,允许使用null值和null键,但不保证映射的顺序
  7. 底层使用数组实现,数组中每一项是个单向链表,即数组和链表的结合体;当链表长度大于一定阈值时,链表转换为红黑树,这样减少链表查询时间。
  8. HashMap在底层将key-value当成一个整体进行处理,这个整体就是一个Node对象。HashMap底层采用一个Node[]数组来保存所有的key-value对,当需要存储一个Node对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Node时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Node。
  9. HashMap进行数组扩容需要重新计算扩容后每个元素在数组中的位置,很耗性能
  10. 采用了Fail-Fast机制,通过一个modCount值记录修改次数,对HashMap内容的修改都将增加这个值。迭代器初始化过程中会将这个值赋给迭代器的expectedModCount,在迭代过程中,判断modCount跟expectedModCount是否相等,如果不相等就表示已经有其他线程修改了Map,马上抛出异常
hashmap

​ HashMap的数据结构(数组+链表+红黑树),桶中的结构可能是链表,也可能是红黑树,红黑树的引入是为了提高效率

​ 可以看到HashMap继承自父类(AbstractMap),实现了Map、Cloneable、Serializable接口。其中,Map接口定义了一组通用的操作;Cloneable接口则表示可以进行拷贝,在HashMap中,实现的是浅层次拷贝,即对拷贝对象的改变会影响被拷贝的对象;Serializable接口表示HashMap实现了序列化,即可以将HashMap对象保存至本地,之后可以恢复状态。

 	// 默认的初始容量是16
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
 	// 默认的填充因子 3/4
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
	// 当桶(bucket)上的结点数大于这个值时会转成红黑树
    static final int TREEIFY_THRESHOLD = 8; 
    // 当桶(bucket)上的结点数小于这个值时树转链表
    static final int UNTREEIFY_THRESHOLD = 6;
    // 桶中结构转化为红黑树对应的table的最小大小
    static final int MIN_TREEIFY_CAPACITY = 64;
    // 存储元素的数组,总是2的幂次倍
    transient Node<k,v>[] table; 
    // 存放具体元素的集
    transient Set<map.entry<k,v>> entrySet;
    // 存放元素的个数,注意这个不等于数组的长度。
    transient int size;
    // 每次扩容和更改map结构的计数器
    transient int modCount;   
    // 临界值 当实际大小(容量*填充因子)超过临界值时,会进行扩容
    int threshold;
    // 填充因子
    final float loadFactor;

面试题

  1. Hash原理,内存数据结构

    ​ 底层使用哈希表(数组+链表),当链表过长试试会将链表转成红黑树来实现

  2. 讲一下hashmap的put方法过程

    ​ a 对key求hash值,然后再计算下标

    ​ b.如果没有碰撞,直接放入桶中

    ​ c.如果碰撞了,以链表方式链接到后面

    ​ d.如果链表长度超过阈值(8),就将链表转成红黑树

    ​ e.如果节点已经存在就替换旧值

    ​ f.如果桶满了(容量+加载因子),则需要扩容

  3. hashmap中hash函数怎么来的?还有哪些实现hash方式?

    a.高16bit 与低bit 做 异或

    b.(n-1)& hash 得到下标

  4. hash怎么解决冲突,讲一下扩容过程,加入一个值在原数组中,现在移动了新数据,位置肯定发生变化了,那是什么定位到这个值新数组中的位置

    a.将新节点加到链表后

    b. 容量扩容为原来的2倍,然后对每个节点重新计算哈希值

    c.这个值可能在两个地方,一个是原下标位置,另一种下标为 <原下标+原容量>的位置

  5. 抛开hashmap, hash冲突有哪些解决办法

    开放定址,莲地址法

LinkedHashMap
  1. LinkedHashMap增加了时间和空间上的开销,但是通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序该迭代顺序可以是插入顺序或者是访问顺序。
  2. LinkedHashMap可以认为是HashMap+LinkedList,即它既使用HashMap操作数据结构,又使用LinkedList维护插入元素的先后顺序。

四个关注点在LinkedHashMap上的答案

关 注 点结 论
LinkedHashMap是否允许空Key和Value都允许空
LinkedHashMap是否允许重复数据Key重复会覆盖、Value允许重复
LinkedHashMap是否有序有序
LinkedHashMap是否线程安全非线程安全
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值