Java集合框架的简单总结

概述

集合框架通过提供有用的数据结构和算法使你能集中注意力于你的程序的重要部分上,而不是为了让程序能正常运转而将注意力于低层设计上。通过这些在无关API之间的简易的互用性,使你免除了为改编对象或转换代码以便联合这些API而去写大量的代码。

集合框架通过提供对有用的数据结构和算法的高性能和高质量的实现使你的程序速度和质量得到提高。因为每个接口的实现是可互换的,所以你的程序可以很容易的通过改变一个实现而进行调整。另外,你将可以从写你自己的数据结构的苦差事中解脱出来,从而有更多时间关注于程序其它部分的质量和性能。

集合框架体系图

Collection接口
List
Queue
Set
ArrayList
LinkedList
HashSet
SortedSet
Map
HashMap
SortedMap
HashTable
TreeMap

Collection接口

Collection接口是集合层级结构的根接口。一个集合代表了一组对象,这组对象被称为集合的元素。一些集合允许重复的元素而其他不允许;一些是有序的而一些是无序的。Java类库中并未提供任何对这个接口的直接实现,而是提供了对于它的更具体的子接口的实现(比如Set接口和List接口)。

我们知道,接口是一组对需求的描述,那么让我们看看Collection接口提出了哪些需求。

Collection接口中定义了以下方法:
在这里插入图片描述
其中的两个toArray方法,他们的功能都是返回此集合的对象数组。T[] toArray方法接收一个arrayToFill参数,当这个参数数组足够大时,就把集合中的元素都填入这个数组(多余空间填null);当此参数不够大时,就会创建一个大小与集合相同,类型与arrayToFill相同的数组,并填入集合元素。

Collection接口的直接子接口主要有三个:List、Set和Queue。下面对其介绍。

List接口

List是一个有序的集合类型(也被称作序列)。使用List接口可以精确控制每个元素被插入的位置,并且可以通过元素在列表中的索引来访问它。列表允许重复的元素,并且在允许null元素的情况下也允许多个null元素。

我们再来看下它定义了哪些方法:
在这里插入图片描述
我们可以看到,列表支持对指定位置元素的读写与移除。

Java类库中常见的实现了List接口的类有:ArrayList, LinkedList,Stack,Vector,AbstractList,AbstractSequentialList等等。

ArrayList

ArrayList是线程不安全的,是一个用数组实现的List。能进行快速的随机访问,但是往列表中间插入和删除元素的时候比较慢。ListIterator只能用在反向遍历ArrayList的场合,不要用它来插入和删除元素,因为相比LinkedList,在ArrayList里面用ListIterator的系统开销比较高。

ArrayList常用方法:

方法名功能
add(E e)在集合末尾新增一个元素
add(int index, E element)在指定位置添加元素
get(int index)获取指定位置的元素
remove(int index)删除指定位置的元素
remove(Object o)删除指定元素
indexOf(Object o)查询指定元素的位置 lastIndexOf也一样,只是从尾部开始遍历
set(int index, E element)设置指定位置的元素值
retainAll(Collection<?> c)求两个集合的交集

LinkedList

LinkedList是线程不安全的,对顺序访问进行了优化。在List中间插入和删除元素的代价也不高。随机访问的速度相对较慢。(用ArrayList吧。)此外它还有addFirst(),addLast(),getFirst(),getLast(),removeFirst()和removeLast()等方法(这些方法,接口和基类均未定义),你能把它当成栈(stack),队列(queue)或双向队列(deque)来用。

LinkedList常用方法:

方法名功能
add(E e)添加一个元素
add(int index, E element)添加一个元素到指定位置
get(int index)获取指定位置的元素
remove(Object o)删除指定元素
indexOf(Object o)查询指定元素的位置 lastIndexOf也一样,只是从尾部开始查询
set(int index, E element)设置指定位置的元素值
peek()获取头节点的元素值,但不删除头节点
poll()获取头节点的元素值,并删除头节点
pop()获取头节点的元素值,并删除头节点,头节点为空则抛出异常
offer(E e)添加新元素到末尾
push(E e)添加新元素到头节点

Stack

栈(Stack)也是一种特殊的线性表,是一种后进先出(LIFO)的结构。
栈是限定仅在表尾进行插入和删除运算的线性表,表尾称为栈顶(top),表头称为栈底(bottom)。
栈的物理存储可以用顺序存储结构,也可以用链式存储结构。

Vector

(与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。)
结论:在考虑并发的情况下用Vector(保证线程的安全)。
在不考虑并发的情况下用ArrayList(不能保证线程的安全)。

Set接口

Set接口与List接口的重要区别就是它不支持重复的元素,至多可以包含一个null类型元素。Set接口定义的是数学意义上的“集合”概念。 Set接口主要定义了以下方法:
在这里插入图片描述
Set接口常用的实现类有HashSet和TreeSet,下面对其进行介绍:

HashSet

使用HashSet存储自定义类对象时,可以在自定义类中重写equals和hashCode方法避免“真实”对象被多次存入,主要原因是集合内不允许有重复的数据元素,在集合校验元素的有效性时(数据元素不可重复),需要调用equals和hashCode验证。
HashSet集合对象如何判断数据元素是否重复:
检查待存对象hashCode值是否与集合中已有元素对象hashCode值相同,如果hashCode不同则表示不重复,如果hashCode相同再调用equals方法进一步检查,equals返回真表示重复,否则表示不重复。

HashSet常用方法:

方法名功能
add(E e)添加一个元素
contains(Object o)如果set包含指定元素,返回true
iterator()返回set中元素的迭代器
toArray()返回包含set中所有元素的数组
toArray(Object[] a)返回包含set中所有元素的数组,返回数组的运行时类型是指定数组的运行时类型
add(Object o)如果set中不存在指定元素,则向set加入
remove(Object o)如果set中存在指定元素,则从set中删除
removeAll(Collection c)如果set包含指定集合,则从set中删除指定集合的所有元素
containsAll(Collection c)如果set包含指定集合的所有元素,返回true。如果指定集合也是一个set,只有是当前set的子集时,方法返回true

TreeSet

TreeSet是一个有序集合,其元素按照升序排列,默认是按照自然顺序排列,也就是说TreeSet中的对象元素需要实现Comparable接口。
TreeSet虽然是有序的,但是并没有具体的索引,当插入一个新的数据元素的时候,TreeSet中原有的数据元素可能需要重新排序,所以TreeSet插入和删除数据元素的效率较低。

TreeSet实现了SortedSet接口,顾名思义这是一种排序的Set集合,查看jdk源码发现底层是用TreeMap实现的,本质上是一个红黑树原理。 正因为它是排序了的,所以相对HashSet来说,TreeSet提供了一些额外的按排序位置访问元素的方法,例如first(), last(), lower(), higher(), subSet(), headSet(), tailSet().

Queue接口

Queue接口是对队列这种数据结构的抽象。一般的队列实现允许我们高效的在队尾添加元素,在队列头部删除元素(First in, First out)。Queue接口还有一个名为Deque的子接口,它允许我们高效的在队头或队尾添加/删除元素,实现了Deque的接口的集合类即为双端队列的一种实现(比如LinkedList就实现了Deque接口)。Queue接口定义了以下方法:
在这里插入图片描述

Map接口

集合框架的第二类接口树。它提供了一组键值的映射。其中存储的每个对象都有一个相应的关键字(key),关键字决定了对象在Map中的存储位置。关键字应该是唯一的,每个key 只能映射一个value。

Map常用方法:
在这里插入图片描述

实现类:HashMap、TreeMap、LinkedHashMap、Hashtable等

HashMap

Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许重复,但允许值重复。
HashMap 是一个最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。
HashMap最多只允许一条记录的键为Null;允许多条记录的值为 Null;
HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力。

HashMap常用方法:

方法名功能
put(K key, V value)将键(key)/值(value)映射存放到Map集合中
get(Object key)返回指定键所映射的值,没有该key对应的值则返回 null
size()返回Map集合中数据数量
clear()清空Map集合
isEmpty ()判断Map集合中是否有数据,如果没有则返回true,否则返回false
remove(Object key)删除Map集合中键为key的数据并返回其所对应value值
values()返回Map集合中所有value组成的以Collection数据类型格式数据
keySet()返回Map集合中所有key组成的Set集合
containsKey(Object key)判断集合中是否包含指定键,包含返回 true,否则返回false
containsValue(Object value)判断集合中是否包含指定值,包含返回 true,否则返回false。

Hashtable

哈希表(HashTable)又叫做散列表,是根据关键码值(即键值对)而直接访问的数据结构。也就是说,它通过把关键码映射到表中一个位置来访问记录,以加快查找速度。
在数据结构中,我们对两种数据结构应该会非常熟悉:数组与链表。数组的特点就是查找容易,插入删除困难;而链表的特点就是查找困难,但是插入删除容易。既然两者各有优缺点,那么我们就将两者的有点结合起来,让它查找容易,插入删除也会快起来。哈希表就是讲两者结合起来的产物。

TreeMap

TreeMap存储K-V键值对,通过红黑树(R-B tree)实现;
TreeMap继承了NavigableMap接口,NavigableMap接口继承了SortedMap接口,可支持一系列的导航定位以及导航操作的方法,当然只是提供了接口,需要TreeMap自己去实现;
TreeMap实现了Cloneable接口,可被克隆,实现了Serializable接口,可序列化;
TreeMap因为是通过红黑树实现,红黑树结构天然支持排序,默认情况下通过Key值的自然顺序进行排序;

LinkedHashMap

大多数情况下,只要不涉及线程安全问题,Map基本都可以使用HashMap,不过HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序。HashMap的这一缺点往往会带来困扰,因为有些场景,我们期待一个有序的Map。
这个时候,LinkedHashMap就闪亮登场了,它虽然增加了时间和空间上的开销,但是通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序。该迭代顺序可以是插入顺序或者是访问顺序。

主要几个框架之间的区别

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值