各自努力,最高处见,笔芯ღ
前言
集合存储的是引用数据类型,Java中常用的集合类型主要为List、Set、Map。
一、List接口
* ArrayList类
1. 简介
① ArrayList底层是通过维护了一个Object数组实现的,使用ArrayList的无参构造函数创建对象时,其默认容量为10。
② 当需要对ArrayList进行扩容时,其容量会自动增长0.5倍,也就是容量会变为原来Object数组长度的1.5倍。
③ ArrayList中允许存在重复元素和null,查询速度快,增加、删除速度慢,效率高但线程不安全。
④ ArrayList属于顺序结构,当数据需要频繁的查询,而增加删除较少的时候,宜使用ArrayList数组存储数据。
2. 拓展
① 查询速度快:ArrayList的内存地址连续(数组等同),可以通过下标快速地找到某个指定的元素。
② 增加速度慢:每次向ArrayList中添加元素时,其首先会判断当前列表容量是否能够容纳该元素。容量充足时可直接向列表中添加元素;容量不足时则会另外创建一个新的更大的数组用于元素的存储,并将所有的元素从旧数组中拷贝到新数组(扩容拷贝低效耗时)。
③ 删除速度慢:每从ArrayList列表中删除一个元素时,其后的所有元素均会轮番向前调整自身的下标(索引),元素调位低效耗时。
ArrayList常用API 测试编写
* LinkedList类
1. 简介
① LinkedList底层数据结构是双向链表(无初始大小和扩容机制),允许存在重复元素和null。
② LinkedList线程不安全,若需要安全的线程可使用List list = Collections.synchronizedList(new LinkedList(···));。
③ LinkedList实现了Deque接口,因此其可以作为双端队列和栈来使用(典型方法有pop();和push();)。
④ LinkedList中所有指定位置的操作都是从头开始遍历进行的 ,因此在查询方面速度较慢。
⑤ LinkedList中的元素是有序的,元素输出顺序和存入顺序一致。
⑥ LinkedList具备fail-fast机制,当两个以上的线程操作同一个列表中的内容时,可能会抛出ConcurrentModificationException异常。
2. 拓展
① LinkedList使用双向链表实现存储,按序号获取数据时需要进行前向或后向遍历,但在插入数据时只需记录当前元素的前后项即可,所以插入速度较快。
② 双向链表的实现原理是将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,对内存的利用率更高。
LinkedList常用API测试编写
二、Set接口
* HashSet
1. 简介
① HashSet在存入数据时会比较元素的哈希值,若哈希值相同则不予存储,因此该集合中的元素唯一。
② HashSet的初始容量为16,存储速度快且支持存入null,同时元素存入顺序与输出顺序不能保证完全一致。
③ HashSet底层对数据的维护采用的是HashMap,而HashMap的线程是不安全的,因此HashSet是非线程安全的。
2. 拓展
① 线程安全是指任何时刻都只有一个线程访问临界资源。通常涉及系统安全的变量一般都是成员变量,局部变量不涉及线程安全。
② Vector(初始容量为10)、statck(堆栈类,先进后出)、Hashtable(初始容量为11)、enumeration(枚举,相当于迭代器)线程安全。
HashSet常用API测试编写
* TreeSet
1. 简介
① TreeSet中存储的数据类型一致,使用Object泛型后数据类型不一致时虽编译通过但运行时报错。
② TreeSet采用红黑树的数据结构存储元素,会对元素进行去重处理、支持元素的自然排序和定制排序。
③ TreeSet中不允许有元素的值为null,同时它也是非同步的,因此其线程不安全。
2. 拓展
* 红黑树特点
A. 红黑树的节点为红色或黑色,根节点为黑色,每个叶子节点都是黑色的空节点(NIL节点);
B. 从每个叶子到根的所有路径上不能有两个连续的红色节点(红节点的孩子不能是红节点);
C. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。
* 红黑树与二叉树
① 红黑树在平衡上进行了优化,仅追求大致平衡。在与平衡二叉树的时间复杂度相差不大的情况下,保证每次插入最多只需要三次旋转就能达到平衡,易于实现。
② 平衡二叉树条件苛刻,追求绝对平衡。在每次插入新节点之后需要进行次数不可预知的平衡旋转,工序繁琐。
TreeSet常用API测试编写
三、Map接口
* HashMap
1. 简介
① HashMap采用了数组和链表的数据结构,在查询和修改方面继承了数组的线性查找和链表的寻址修改。
② HashMap是一个散列桶(数组和链表),其中采用键值对的形式存储数据,键不可重复,值可以重复。
③ HashMap中的元素无序,存储元素采用put();,获取元素采用get();。
④ HashMap的初始容量为16,同时允许存入的值为null。
2. 拓展
① 使用put();向HashMap中存储数据时,HashMap会调用其hashCode();来计算对象的hashCode值,随后会找到对应的bucket位置来存储对象
② 使用get();从HashMap中获取对象时,HashMap会调用键的equals();来查找键值对,随后返回指定的对象。
③ 当计算到两个对象的hashCode值一样时会发生hash碰撞,HashMap会使用链表法将对象存储在链表的下一个节点中避免碰撞。
Tips:解决hash碰撞 - 开放地址法,再哈希法,链地址法(拉链法)、建立公共溢出区。
HashMap常用API测试编写
* TreeMap
1. 简介
① TreeMap是一个有序的Key - Value集合,其实现采用的是红黑树,且支持序列化 。
② TreeMap中元素的添加顺序与输出顺序不一定一致,且其中的元素唯一,键不可重复,值可以重复。
③ TreeMap默认会对键进行排序,因此键必须实现自然排序和定制排序中的一种。
④ TreeMap参照了红黑树的存储结构,每个Key - Value存储在一个Entry里,TreeMap的Entry实质是红黑树的一个节点。
2. 拓展
① 遍历TreeMap时首先需要通过entrySet();(或者keySet();或者value();)获得相应的集合,再通过Iterator对集合元素进行迭代。
② TreeMap的增删改查以及统计相关的操作的时间复杂度为O(logn),可以运用于需要基于排序的统计以及需要快速增删改查和保证遍历、插入顺序一致的存储功能的实现。
TreeMap常用API测试编写