JAVA集合框架详解,看这一篇就够了

1. 集合简介

集合就是存放对象的容器。定义了对多个对象进行操作的常用方法。可实现数组的功能。
相比于数组来说,集合有以下的区别:

  1. 数组长度固定,集合长度不固定
  2. 数组可以存储基本类型和引用类型,集合只能存储引用类型(对象)
  3. 集合中存放的都是对象的引用,而非对象本身。所以我们称集合中的对象就是集合中对象的引用。对象本身还是存放在堆内存中
  4. 数组存储的元素必须是同一个数据类型,集合存储的对象可以是不同数据类型的

Java集合类主要由两个根接口 CollectionMap 派生出来的。

其中, Collection 又派生出了三个子接口,其关系如下图所示:

Collection体系

  • List代表了有序可重复集合,可直接根据元素的索引来访问
  • Set代表无序不可重复集合,只能根据元素本身来访问
  • Queue是队列集合

Map 接口的派生关系如下:

Map体系

下面对 CollectionMap 接口的一些重要实现类和接口进行介绍,涉及到实现类的具体方法时,该文章仅列出具体的函数签名,就不一一对各个函数进行实验和举例了。

2. Collection体系

Collection 接口定义的方法中常用的如下:

方法签名功能
boolean add(Object obj)添加一个对象
boolean addAll(Collection c) 将一个集合中的所有对象添加到此集合中
void clear() 清空此集合中的所有对象
boolean contains(Object o)检查此集合中是否包含o对象
boolean equals(Object o)比较此集合是否与指定对象相等
boolean isEmpty() 判断此集合是否为空
boolean remove(Object o)在此集合中移除o对象
int size()返回此集合中的元素个数
Object[ ] toArray()将此集合转换成数组

Collection 接口的实现类都实现了其方法,所以上述方法在任何一个实现类中都可以使用。

2.1 List

List 接口也定义了一系列常用的方法,一般的常用方法如下,

方法签名功能
void add(int index, Object o) 在index位置插入对象o
boolean addAll(int index, Collection c)将一个集合中的元素添加到此集合中的index位置
Object get(int index)返回集合中指定位置的元素
List subList(int fromIndex, int toIndex)返回 [fromIndex, toIndex) 之间的集合的元素
list.indexOf()获取某个元素所在索引

List 接口的实现类有 ArrayList, Vector, LinkedList,其中最重要的当属 ArrayList 了,下面我们分别对其进行讲解。

2.1.1 ArrayList

ArrayList 的底层是用数组进行实现的,这就导致了其随机查询的速度快除元素的速度慢的特点。

其默认初始的数组大小是10个,当元素逐渐增长导致空间不够的时候,数组长度每次增长为原来的1.5倍,注意,如果没有向其中添加任何元素,那么其容量为0。

ArrayList 是线程不安全的,没有同步方法,如果需要进行多线程访问必须自己实现访问同步,即创建示例如下:

List<String> list = Collections.synchronizedList(new ArrayList<>());

ArrayList 的常用方法列表如下:

方法签名功能
void sort(Comparator<? super E> c)对 ArrayList 的元素进行排序,动态改变数组,无返回值
Object clone()复制一份 ArrayList
E set(int index, E element)替换 ArrayList 中指定索引的元素
Object[] toArray()将 ArrayList 转为数组
boolean retainAll(Collection<?> c)保留 ArrayList 中在指定集合中也存在的那些元素
void removeRange(int fromIndex, int toIndex)删除 [fromIndex, toIndex) 之间的元素

2.1.2 LinkedList

LinkedList 的底层是用链表进行实现的,因此其查询的速度慢,但是删除和增加元素的速度快

LinkedList 也是线程不同步的,如果需要进行多线程访问必须自己实现访问同步,即创建示例如下:

List<String> list = Collections.synchronizedList(new LinkedList<>());

LinkedList 实现了 Queue 接口,可作为队列使用, 实现了 List 接口,可进行列表的相关操作,实现了 Deque 接口,可作为队列使用,实现了 Cloneable 接口,可实现克隆,实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

LinkedList 常用方法如下:

方法签名功能
boolean offer(E e)向链表末尾添加元素,返回是否成功,成功为 true,失败为 false
boolean offerFirst(E e)头部插入元素,返回是否成功,成功为 true,失败为 false。
boolean offerLast(E e)尾部插入元素,返回是否成功,成功为 true,失败为 false。
E poll()删除并返回第一个元素
E peek()返回第一个元素
E removeFirst()删除并返回第一个元素。
E removeLast()删除并返回最后一个元素

2.1.3 Vector

Vector 底层也是数组实现的,当然也就拥有了其查询速度快,增加删除元素慢的特点。

但是, VectorArrayList 不同的地方在于, Vector 的运行速度比 ArrayList 慢一些,其访问是线程安全的。

2.2 Set

Set 里面的元素是无序的,这也就导致里面的元素是没有下标的,无法靠下标的索引来进行定位,Set 集合的特点是不保存重复的元素,在 Set 接口的实现类中,我们重点来看一下 HashSet 这个实现类。

HashSet 的存储结构是哈希表,实现方式是数组与红黑树的结合,HashSet 里面的元素可以包含 null 元素,HashSet 同样不是线程安全的,如果需要多线程进行访问,那么可以使用下面的方法进行创建:

HashSet<String> s = Collections.synchronizedSet(new HashSet<>());

HashSet 的数组初始容量为16,负载因子默认为0.75,即如果元素达到当前总容量的0.75则自动增加容量。同时,该实现类也可以重写 hashCodeequals 方法, hashCode 方法是哈希表存储的映射方式,重写后则采用重写的映射方式,equals 是判断是否重复的方法,如果其返回为 true ,则认为是重复的。

HashSet 内的元素无法进行索引,所以如果想要访问其中的元素,可以对其进行迭代遍历,其经常使用的方法如下:

方法签名功能
boolean contains​(Object o)如果此set包含指定的元素,则返回 true
int size()返回此集合中的元素数(基数)
boolean remove​(Object o)如果存在,则从该集合中移除指定的元素

2.3 Queue

Queue 是一种先进先出的数据结构,其下面还有一个接口 Deque (双端队列),它的实现类有多种,包括LinkedList(链表)实现,ArrayDeque(数组实现的双端队列),PriorityQueue(优先级队列)等,其主要使用的方法为:

方法签名功能
boolean add(E e)增加一个元素
boolean offer(E e);增加一个元素到队尾并返回true
E poll()将队首的元素删除,并返回该元素
E peek()返回队首的元素,但不进行删除操作

2.4 Collection工具类

Collection 除了存储意外,还实现了一些集合常用的方法,可以方便的对集合进行操作。

方法签名功能
void shuffle(List<?> list)打乱list集合元素的顺序
<T> void sort(List<T> list);排序
<T> void sort(List<T> list, Comparator<T> c)根据指定的规则进行排序
<T> int binarySearch(List<T> list,T key)以二分查找法查找元素
<T> void copy (List<T> dest,List<T> src)拷贝集合中的元素
<T> int fill(List<T> list, T obj)使用指定的元素填充集合
<T> int binarySearch(List<T> list,T key)以二分查找法查找元素
<T> void swap(List<?> list, int i, int j)交换集合中指定的位置的元素
<T> void max/min(Collection<T> coll)根据默认的自然排序获取最大/最小值

3. Map 体系

Collection 父接口需要掌握的基本就是上面的几个实现类和接口,接下来我们对 Map 父接口的重要实现类进行介绍, Map 存储的特点是 Key-Value 形式的方式进行存储,其中存储的元素无序、无下标,Key 不能重复,Value可以重复。

Map 父接口下的实现类有很多,它们都是线程不安全的,比如:

  • HashMap: 使用哈希表实现的散列表,提供常数时间的插入和检索操作 ( O ( 1 ) ) (O(1)) (O(1)),不保证遍历顺序,即迭代器返回元素的顺序是不确定的,允许存储 null 键和 null 值。
  • TreeMap: 基于红黑树实现的有序映射,按照键的自然顺序或者自定义比较器进行排序,查找、插入、删除操作的时间复杂度为 O ( l o g n ) O(log n) O(logn),不允许存储 null 键,但可以存储 null 值。
  • WeakHashMap: 基于哈希表实现的弱键映射,键是使用弱引用存储的,当键没有强引用时,在垃圾回收时可能被自动移除,适用于临时缓存和内存敏感的应用场景,允许存储 null 键和 null 值。
  • LinkedHashMap: 基于哈希表和双向链表实现,保持元素的插入顺序或者访问顺序,遍历顺序可以是插入顺序或者访问顺序,查找操作的时间复杂度为 O ( 1 ) O(1) O(1) ,允许存储 null 键和 null 值。
  • IdentityHashMap: 基于哈希表实现的特殊映射,通过引用相等性比较键和值,键和值的相等性是基于对象的内存地址而不是 equals 方法,不保证遍历顺序,允许存储 null 键和 null 值。

除此之外还有一些类型的 Map ,我们这里主要了解 HashMap

3.1 HashMap

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射,HashMap 是线程不安全的,如果想要创建一个线程安全的 HashMap ,那么可以使用下面的语句初始化:

Map<String, Integer> synchronizedMap = Collections.synchronizedMap(new HashMap<>());

HashMap 常用的方法如下:

方法签名功能
V put(K key, V value)将键/值对添加到 hashMap 中
void clear()删除 hashMap 中的所有键/值对
int size​()计算 hashMap 中键/值对的数量
boolean remove(Object key, Object value)删除 hashMap 中指定键 key 的映射关系
boolean containsKey(Object key)检查 hashMap 中是否存在指定的 key 对应的映射关系
boolean containsValue(Object value)检查 hashMap 中是否存在指定的 value 对应的映射关系
V get(Object key)获取指定 key 对应对 value
V getOrDefault(Object key, V defaultValue)获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
Set<Map.Entry<K,V>> entrySet()返回 hashMap 中所有映射项的集合集合视图。
Set<K> keySet()返回 hashMap 中所有 key 组成的集合视图
Collection<V> values()返回 hashMap 中存在的所有 value 值
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值