Java集合框架的知识总结
一、简介
所有集合类都位于java.util包下。Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些接口或实现类。
Set和List接口是Collection接口派生的两个子接口,Queue是Java提供的队列实现,类似于List。
Map实现类用于保存具有映射关系的数据(key-value)。
Set、List和Map可以看做集合的三大类。
List是有序的Collection,集合中的元素可以重复。用户能够使用索引来访问List中的元素。 List使用iterator()方法进行遍历。
▼ArrayLis异步的,线程非安全,执行效率高。
▼Vector是同步的,线程安全,执行效率低。
LinkedList(链表)-是双向链表,每个节点都有两个指针指向上一节点和下一节点。
Set是无序集合,集合中的元素不能重复。访问集合中的元素只能根据元素本身进行访问。
Map集合中保存key-value键值对的形式,访问时只能根据每项元素的key来访问其value。
▼HashMap是异步的,线程非安全,其key和value允许null,执行效率高。
▼Hashtable是同步的,线程安全,,其key和value不允许null,执行效率低。
在讨论之前,先来看几个面试中的经典问题。
1 Collection和 Collections的区别。
2 List, Set, Map是否继承自Collection接口。
3 ArrayList和Vector的区别。
4 HashMap和Hashtable的区别。
篇尾有答案,我们开始正题。
二、Collection接口
Collection接口是List、Set和Queue接口的父接口,同时可以操作这三个接口。
常规的方法:
-
单元素添加、删除操作:
boolean add(Object o):将对象添加给集合;
boolean remove(Object o):如果集合中有与o相匹配的对象,则删除对象o。
-
查询操作:
int size():返回当前集合中元素的数量;
boolean isEmpty():判断集合中是否有任何元素;
boolean contains(Object o):查找集合中是否含有对象o;
Iterator iterator():返回一个迭代器,用来访问集合中的各个元素;Collection不提供get()方法。如果要遍历Collectin中的元素,就必须用Iterator。
-
组操作:作用于元素组或整个集合
boolean containsAll(Collection c):查找集合中是否含有集合c中所有元素;
boolean addAll(Collection c) :将集合c中所有元素添加给该集合;
void clear():删除集合中所有元素;
void removeAll(Collection c) :从集合中删除集合c中的所有元素;
void retainAll(Collection c) :从集合中删除集合c中不包含的元素(实质是求两集合交集)
-
Collection转换为Object数组:
Object[] toArray():返回一个内含集合所有元素array;
Object[] toArray(Object[] a):返回一个内含集合所有元素的array。运行期返回的array和参数a的型别相同,需要转换为正确型别。此外,您还可以把集合转换成其它任何其它的对象数组。
LinkedList类和ArrayList类在“集合框架 ”中有两种常规的 List实现:ArrayList和 LinkedList。使用两种 List 实现的哪一种取决于您特定的需要。如果要支持随机访问,而不必在除尾部的任何位置插入或除去元素,那么,ArrayList提供了可选的集合。但如果,您要频繁的从列表的中间位置添加和除去元素,而只要顺序的访问列表元素,那么,LinkedList实现更好。 “ArrayList和LinkedList都实现 Cloneable接口,都提供了两个构造函数,一个无参的,一个接受另一个Collection”
LinkedList类:
LinkedList类另外添加了一些处理列表两端元素的方法。
-
void addFirst(Object o):将对象o添加到列表的开头
void addLast(Object o):将对象o添加到列表的结尾
(2) ObjectgetFirst(): 返回列表开头的元素
Object getLast():返回列表结尾的元素
-
Object removeFirst():删除并且返回列表开头的元素
Object removeLast():删除并且返回列表结尾的元素
-
LinkedList():构建一个空的链接列表
LinkedList(Collection c):构建一个链接列表,并且添加集合c的所有元素
使用这些新方法,您就可以轻松的把LinkedList当作一个堆栈、队列或其它面向端点的数据结构。
ArrayList类:
1.ArrayList概述:
ArrayList类封装了一个动态再分配的Object[]数组。每个ArrayList对象有一个capacity[kəˈpæsiti](容量)。这个capacity表示存储列表中元素的数组的容量。当元素添加到ArrayList时,它的capacity在常量时间内自动增加。在向一个ArrayList对象添加大量元素的程序中,可使用ensureCapacity方法增加capacity。这可以减少增加重分配的数量(因为自动分配容量的规则是:……)。
(1)void ensureCapacity(int minCapacity):将ArrayList对象容量增加minCapacity
(2) void trimToSize():整理ArrayList对象容量为列表当前大小。程序可使用这个操作减少ArrayList对象存储空间。
注意,此实现不是同步的。如果多个线程同时访问一个 ArrayList 实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。(结构上的修改是指任何添加或删除一个或多个元素的操作,或者显式调整底层数组的大小;仅仅设置元素的值不是结构上的修改。)
2. ArrayList的实现:
对于ArrayList而言,它实现List接口、底层使用数组保存所有元素。其操作基本上是对数组的操作。
RandomAccess接口
一个特征接口。该接口没有任何方法,不过你可以使用该接口来测试某个集合是否支持有效的随机访问。ArrayList和Vector类用于实现该接口.
Set接口
Set接口继承 Collection 接口,而且它不允许集合中存在重复项,每个具体的 Set实现类依赖添加的对象的 equals()方法来检查独一性。Set接口没有引入新方法,所以Set就是一个Collection,只不过其行为不同。
HashSet
HashSet按Hash算法来存储集合的元素,因此具有很好的存取和查找性能。
HashSet的特点:
(1)HashSet不是同步的,多个线程访问是需要通过代码保证同步
(2)集合元素值可以使null。
HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值也相等。
TreeSet
三、数据结构
(1)链表
(2)数组列表
(3)Hash表(散列表)
Hash表是一种数据结构,用来查找对象。Hash表为每个对象计算出一个整数,称为Hash Code(哈希码)。
Hash表是个链接式列表的阵列。每个列表称为一个buckets(桶有的资料也叫哈希表元)。对象位置的计算 index = HashCode % bucketsCounts (HashCode为对象哈希码,bucketsCounts为桶总数)。当你添加元素时,有时你会遇到已经填充了元素的桶,这种情况称为Hash Collisions(哈希冲突)。这时,你必须判断该元素是否已经存在于该哈希表中。如果哈希码是合理地随机分布的,并且桶的数量足够大,那么哈希冲突的数量就会减少。同时,你也可以通过设定一个初始的桶数量来更好地控制哈希表的运行。初始桶的数量为 buckets = size * 150% + 1 (size为预期元素的数量)。如果哈希表中的元素放得太满,就必须进行rehashing(再哈希)。再哈希使桶数增倍,并将原有的对象重新导入新的桶中,而原始的桶被删除。load factor(加载因子)决定何时要对哈希表进行再哈希。在Java编程语言中,加载因子默认值为0.75,默认哈希表元为101。
散列表可以实现几种重要的数据结构,其中最简单的是Set类型。Set是没有重复的元素的集合。Set的add方法首先是在集合中查找需要添加的对象,如果存在就添加,不添加(不做任何变话)。Java集合类库中提供了一个hashSet类,它实现基于散列表。
(4)树集
三、知识补充:
(1) LinkedList.add方法将对对象添加到链表(列表)尾部。但是常常需要将元素添加到链表的中间。由于迭代器是描述集合中的位置的,所以这种依赖于位置的add方法和更改元素的set方法将由迭代器负责。只有对自然有序的集合使用迭代器添加元素才有实际意义。
下面贴出代码:
四、遍历集合
两种遍历集合的方法Iterator接口和foreach循环
1、Iterator接口:
Iterator也是Java集合框架的成员,主要用于遍历(即迭代访问)Collection集合中的元素,也
称为迭代器。
提供的三种方法:
boolean hasNext():返回集合里的下一个元素。
Object next():返回集合里下一个元素。
void remove();删除集合里上一次next方法返回的元素。
2、使用foreach循环遍历集合元素。
格式:for(元素类型 t 元素变量 x:遍历对象A) {
//程序块
}
说明:
(1)foreach简化了对数组和集合的遍历,如果不希望遍历整个集合,或者在循环内部需要操作下标值就需要使用传统的for循环。
(2)简化了编程,提高了代码的可读性和安全性(不用怕数组越界)。
(3)foreach一般结合泛型使用
面试题答案
Collection和 Collections的区别。
Collections是个java.util下的类,它包含有各种有关集合操作的静态方法。
Collection是个java.util下的接口,它是各种集合结构的父接口。
List, Set, Map是否继承自Collection接口?
List,Set是 Map不是
ArrayList和Vector的区别。
一.同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的
二.数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半
HashMap和Hashtable的区别
一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
三.值:只有HashMap可以让你将空值作为一个表的条目的key或value