Java集合

Java集合是学习Java中必须掌握的,面试也会经常问道.

Java集合框架图

image-20210618092536178

从上面可以看出,集合主要分两大类,一种是Collection,存储的是元素集合,另一种是Map,存储Key/Value,其中Collection又分为ListSetQueue在下面也是一些抽象类,最后是具体实现类,常用的有 ArrayListLinkedListHashSet、LinkedHashSet、HashMap、LinkedHashMap等等.

集合接口

接口 接口描述
Collection Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素,Java不提供直接继承Collection的类,只提供继承于的子接口(如List和Set).Collection接口存储一组不唯一,无序的对象.
List List是有序的Collection,能精确的控制每一个元素的插入位置,能通过索引访问List中的元素,允许有相同的元素.List接口存储一组不唯一,有序的对象.
Set 具有和Collection完全一样的接口,Set不保存重复的元素,Set接口存储一组唯一,无需的对象.
SortedSet 继承于Set保存有序的集合
Map 存储键值对的对象
Map.Entry 描述Map中的一个元素,是Map的内部接口
SortedMap 继承于Map,使Key保存在升序排序
Enumeration 这是一个传统的接口和定义的方法,通过它可以枚举(一次获得一个)对象集合中的元素。这个传统接口已被迭代器取代。

Set和List的区别

  1. Set接口保存实例存储的是无序的,不重复的,List接口则是有序的,可以重复的元素
  2. Set检索效率低下,删除和插入如效率高,插入和删除不会引起元素位置的改变 <实现类有HashSet,TreeSet>
  3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度,查找元素效率高,插入和删除效率低,因为会引起其他元素位置改变**<实现类有ArrayList,LinkedList,Vector>**

常用集合

ArrayList

ArrayList是可以动态修改的数组,于普通数组的区别就是没有固定的大小限制,我们可以添加或删除数据

ArrayList继承了AbstractList并实现了List接口

image-20210618103119745

ArrayList常用方法

方法 描述
add() 将元素插入到指定位置的 arraylist 中
addAll() 添加集合中的所有元素到 arraylist 中
clear() 删除 arraylist 中的所有元素
clone() 复制一份 arraylist
contains() 判断元素是否在 arraylist
get() 通过索引值获取 arraylist 中的元素
indexOf() 返回 arraylist 中元素的索引值
removeAll() 删除存在于指定集合中的 arraylist 里的所有元素
remove() 删除 arraylist 里的单个元素
size() 返回 arraylist 里元素数量
isEmpty() 判断 arraylist 是否为空
subList() 截取部分 arraylist 的元素
set() 替换 arraylist 中指定索引的元素
sort() 对 arraylist 元素进行排序
toArray() 将 arraylist 转换为数组
toString() 将 arraylist 转换为字符串
ensureCapacity() 设置指定容量大小的 arraylist
lastIndexOf() 返回指定元素在 arraylist 中最后一次出现的位置
retainAll() 保留 arraylist 中在指定集合中也存在的那些元素
containsAll() 查看 arraylist 是否包含指定集合中的所有元素
trimToSize() 将 arraylist 中的容量调整为数组中的元素个数
removeRange() 删除 arraylist 中指定索引之间存在的元素
replaceAll() 将给定的操作内容替换掉数组中每一个元素
removeIf() 删除所有满足特定条件的 arraylist 元素
forEach() 遍历 arraylist 中每一个元素并执行特定操作

排序

Collections.sort(YourList);

LinkedList

链表是一种常见的基本数据结构,是一种线性表,但并不会按线性顺序存储数据,而是在每一个节点里存到下一个节点的地址.

链表有单向和双向链表之分.

单向链表包含两个值:当前节点的值和指向下一个节点的链接

image-20210618104604427

双向链表有三个数值:向前的节点链接,数值,向后的节点链接

image-20210618104645755

ArrayList相比,LinkedList的增加和删除效率更高,而查找和修改的操作效率低

以下情况使用ArrayList

  • 频繁访问列表的某一个元素
  • 只需要在列表末尾添加或删除操作

以下情况使用LinkedList

  • 需要通过循环迭代来访问列表中的某些元素
  • 需要频繁的在列表开头,中间,末尾等位置进行添加和删除元素操作

LinkedList 继承了 AbstractSequentialList 类。

LinkedList 实现了 Queue 接口,可作为队列使用。

LinkedList 实现了 List 接口,可进行列表的相关操作。

LinkedList 实现了 Deque 接口,可作为队列使用。

LinkedList 实现了 Cloneable 接口,可实现克隆。

LinkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

image-20210618105347249

常用方法

方法 描述
public boolean add(E e) 链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public void add(int index, E element) 向指定位置插入元素。
public boolean addAll(Collection c) 将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。
public boolean addAll(int index, Collection c) 将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。
public void addFirst(E e) 元素添加到头部。
public void addLast(E e) 元素添加到尾部。
public boolean offer(E e) 向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public boolean offerFirst(E e) 头部插入元素,返回是否成功,成功为 true,失败为 false。
public boolean offerLast(E e) 尾部插入元素,返回是否成功,成功为 true,失败为 false。
public void clear() 清空链表。
public E removeFirst() 删除并返回第一个元素。
public E removeLast() 删除并返回最后一个元素。
public boolean remove(Object o) 删除某一元素,返回是否成功,成功为 true,失败为 false。
public E remove(int index) 删除指定位置的元素。
public E poll() 删除并返回第一个元素。
public E remove() 删除并返回第一个元素。
public boolean contains(Object o) 判断是否含有某一元素。
public E get(int index) 返回指定位置的元素。
public E getFirst() 返回第一个元素。
public E getLast() 返回最后一个元素。
public int indexOf(Object o) 查找指定元素从前往后第一次出现的索引。
public int lastIndexOf(Object o) 查找指定元素最后一次出现的索引。
public E peek() 返回第一个元素。
public E element() 返回第一个元素。
public E peekFirst() 返回头部元素。
public E peekLast() 返回尾部元素。
public E set(int index, E element) 设置指定位置的元素。
public Object clone() 克隆该列表。
public Iterator descendingIterator() 返回倒序迭代器。
public int size() 返回链表元素个数。
public ListIterator listIterator(int index) 返回从指定位置开始到末尾的迭代器。
public Object[] toArray() 返回一个由链表元素组成的数组。
public T[] toArray(T[] a) 返回一个由链表元素转换类型而成的数组。

HashMap

HashMap是一个散列表,存储键值对,实现了Mao接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步.

HashMap是无序的,HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。

image-20210618112102975

HashMap的key和Value可以相同也可以不相同

常用方法

方法 描述
clear() 删除 hashMap 中的所有键/值对
clone() 复制一份 hashMap
isEmpty() 判断 hashMap 是否为空
size() 计算 hashMap 中键/值对的数量
put() 将键/值对添加到 hashMap 中
putAll() 将所有键/值对添加到 hashMap 中
putIfAbsent() 如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。
remove() 删除 hashMap 中指定键 key 的映射关系
containsKey() 检查 hashMap 中是否存在指定的 key 对应的映射关系。
containsValue() 检查 hashMap 中是否存在指定的 value 对应的映射关系。
replace() 替换 hashMap 中是指定的 key 对应的 value。
replaceAll() 将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。
get() 获取指定 key 对应对 value
getOrDefault() 获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
forEach() 对 hashMap 中的每个映射执行指定的操作。
entrySet() 返回 hashMap 中所有映射项的集合集合视图。
keySet() 返回 hashMap 中所有 key 组成的集合视图。
values() 返回 hashMap 中存在的所有 value 值。
merge() 添加键值对到 hashMap 中
compute() 对 hashMap 中指定 key 的值进行重新计算
computeIfAbsent() 对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中
computeIfPresent() 对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。

HashSet

HashSet基于HashMap来实现,是一个不允许有重复元素的集合.

HashSet允许有空值.是无序的,不是线程安全的.

HashSet实现了Set接口

image-20210618113323485