Collection
集合包含Collection和map接口,Collection又由两个子接口List和Set构成,每个子接口又有自己不同的实现类。
List接口(有序,值可重复)
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引来访问List中的元素,类似数组。List允许有相同的元素。
实现List接口的常用类有LinkedList,ArrayList,Vector。
ArrayList类:是最常用的List实现类,它实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
ArrayList(可以理解成动态数组)
-
add:添加单个元素
-
remove:删除指定元素
-
contains:查找元素是否存在
-
size:获取元素个数
-
isEmpty:判断是否为空
-
clear:清空
-
addAll:添加多个元素
-
containsAll:查找多个元素是否都存在
-
removeAll:删除多个元素
LinkedList类: LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
LinkedList的底层操作机制
(1)LinkedList底层维护了一个双向链表
(2)LinkedList中维护了两个属性first和last分别指向首节点和尾节点
(3)每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表。
(4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。
(5)一个简单的双向链表:
ArrayList和LinkedList的比较:
ArrayList:
底层结构:可变数组;
增删的效率:较低;
改查的效率:较高;
LinkedList:
底层结构:双向链表;
增删的效率:较高、通过链表追加;
改查的效率:较高;
如何选择ArrayList和LinkedList:
- 如果我们改查的操作多,选择ArrayList
- 如果我们增删的操作多,选择LinkedList
- 一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList
- 在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外一个模块是LinkedList。
Vector类:
Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的 Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
遍历方式
迭代器 Iterator:
- 迭代器主要用于遍历Collection集合中的元素
- 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象,即可以返回一个迭代器
- 仅用于遍历集合,Iterator本身并不存放对象。
增强for循环
可以替代iterator迭代器,特点:增强for就是简化版的iterator本质一样。只能用于遍历集合或数组。
for(元素类型 元素名:集合名或数组名){
访问元素
}
Set接口(值不可重复)
Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。 很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。
注意:必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。
- 无序(添加和取出的顺序不一致,没有索引)
- 不允许重复元素,所以最多包含一个null
set接口的遍历方式
同Collection的便利方式一样,因为Set接口是Collection接口的子接口
- 可以使用迭代器
- 增强for
- 不能使用索引的方式来获取
hashset
- hashset实现了set接口
- hashset实际上是hashmap
- 可以存放null值,但是只能有一个
- hashset不保证元素是有序的,取决于hash后,再确定索引的结果
- 不能有重复元素/对象,在前面set接口使用已经讲过
hashset底层是hashmap, hashmap底层是(数组+链表+红黑树)
LinkedHashSet
底层数据结构是双向链表和哈希表,有序。
由链表保证元素有序,由哈希表保证元素唯一。
TreeSet
底层数据结构是红黑树,内部实现排序,也可以自定义排序规则。
自然排序、比较器排序保证元素排序。根据比较的返回值是否是0来保证元素唯一性。
ArraySet
底层数据结构是双数组,有序。
Map接口
Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个 value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。
jdk8
- Map与Collection并列存在,用于保存具有映射关系的数据Key-Value
- Map中的Key和value可以是任何引用类型的数据,会封装到HashMap
- Map中的key不允许重复,原因和HashSet一样
- map中的value可以重复
- map中的key可以为null,value也可以为null,注意key为null,只能有一个,value为null可以有多个
- 常用String类作为Map的key
- key和value之间存在单向一对一关系,即通过指定的key总能找到对应的value
![
常用方法:
- put
- remove
- get
- size
- isEmpty
- clear
- containsKey
Map遍历方法
- containsKey查找键是否存在
- keySet获取所有的键
- entrySet获取所有关系k-v
- values获取所有值
小结:
- Map接口的常用实现类:HashMap,Hashtable,Properties
- HashMap是Map接口使用频率最高的实现类
- HashMap是以key-val对的方式来存储数据
- key不能重复,但是是值可以重复,允许使用null键和null值
- 如果添加相同的key,则会覆盖原来的key-val,等同于修改,(key不会替换,val会替换)
- 与HashSet不一样,不保证映射的顺序,因为底层是以hash表的方式来存储的。
- HashMap没有实现同步,因此是线程不安全的。
Hashtable类
Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。Hashtable是同步的。
HashMap类
HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap 的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。
-
存放的元素是键值对:即k-v
-
hashtable的键和值都不能为null,否则抛出NullPointerException
-
hashtable使用方法基本上和hashmap一样
-
hashtable是线程安全的,hashmap是线程不安全的
扩容机制:
properties
- Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值对的形式来保存数据。
- 他的使用特点和Hashtable类似
- Properties还可以用于从xxx.properties文件中,加载数据到properties类对象,并进行读取和修改
- 说明:工作后 xxx.properties文件通常作为配置文件,这个知识点在IO流举例。
集合选型规则
- 先判断存储的类型(一组对象[单列]或一组键值对[双列])
- 一组对象[单列]:Collection接口
允许重复: List
增删多: LinkedList [底层维护了一个双向链表]
改查多: ArrayList [底层维护Object类型的可变数组]
不允许重复: Set
无序: HashSet [底层是HashMap,维护了一个哈希表 即(数组+链表+红黑树)]
排序: TreeSet
插入和取出顺序一致: LinkedHashSet,维护数组+双向链表
- 一组键值对:Map
键无序:HashMap [底层是:哈希表 jdk7:数组+链表, jdk8:数组+链表+红黑树]
键排序:TreeMap
键插入和取出顺序一致:LinkedHashMap
读取文件:Properties