Java基础 | 集合类大概介绍

1. 集合简介

在这里插入图片描述
图片来源

2. Collection接口

Collection接口是最基本的集合接口,它不提供直接的实现,其表示一个独立元素的序列,这些元素都服从一条或多条规则。如有些按照顺序插入,有些允许重复而有些不允许。

2.1 List接口(有序、可重复)

List接口为Collection直接接口。List所代表的是有序的Collection,即它用某种特定的插入顺序来维护元素顺序。用户可以对列表中每个元素的插入位置进行精确地控制,同时可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。常用List实现类有:ArrayList、LinkedList、Vector。

2.1.1 ArrayList

ArrayList是一个动态数组。它允许任何符合规则的元素插入甚至包括null。每一个ArrayList都有一个初始容量(10),该容量代表了数组的大小。
ArrayList擅长于随机访问。同时ArrayList是非同步的。

2.1.2 LinkedList

LinkedList同样是实现了List接口的一种集合,它是一个双向链表。所以它除了有ArrayList的基本操作方法外还额外提供了get,remove,insert方法在LinkedList的首部或尾部。

由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。
与ArrayList一样,LinkedList也是非同步的。

常用方法
方法名作用
add尾插入
peek查看头结点(空的话返回null)
poll头删除并返回(空的话返回null)
push头插入
pop头删除并返回(null的话抛出NoSuchElementException异常)

2.1.3 Vector

与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。

2.2 Set接口(无序、不能重复)

Set是一种不包括重复元素的Collection。它维持它自己的内部排序,所以随机访问没有任何意义。与List一样,它同样运行null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,同时要注意任何可变对象,如果在对集合中元素进行操作时,导致e1.equals(e2)==true,则必定会产生某些问题。常用Set实现类有:EnumSet、HashSet、TreeSet。

2.2.1 EnumSet

枚举的专用Set。所有的元素都是枚举类型

2.2.2 HashSet

HashSet堪称查询速度最快的集合,因为其内部是以HashCode来实现的。它内部元素的顺序是由哈希码来决定的,所以它不保证set 的迭代顺序
说明: 要求添加进Set中的元素所在的类,一定要重写equals()hashCode()方法。进而保证Set中元素的不可重复性

2.2.3 TreeSet

基于TreeMap,生成一个总是处于排序状态的set,内部以TreeMap来实现。它是使用元素的自然顺序对元素进行排序,或者根据创建Set 时提供的 Comparator 进行排序,具体取决于使用的构造方法

3. Map接口(键值对、键唯一、值不唯一)

Map是由一系列键值对组成的集合,提供了key到Value的映射。同时它也没有继承Collection。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,当然value值可以相同。常用Map实现类有:HashMap、TreeMap、Hashtable。

3.1 HashMap

以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会通过哈希转换函数将元素的哈希地址转换成数组中存放的索引,如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来,可能通过查看HashMap.Entry的源码它是一个单链表结构。

3.2 Hashtable

Hashtable是以哈希表数据结构实现的,解决冲突时与HashMap也一样也是采用了散列链表的形式,不过性能比HashMap要低

3.3 TreeMap

特点:按照添加进Map中的元素的“Key”的指定属性进行排序。要求:Key必须是同一个类的对象
键以某种排序规则排序,内部以red-black(红-黑)树数据结构实现,实现了SortedMap接口

3.4 ConcurrentHashMap

(待完善…)

4. Iterator迭代器

所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口,主要包含以下三种方法:

  1. hasNext():是否还有下一个元素。
  2. next():返回下一个元素。
  3. remove():删除当前元素。

5. 集合的遍历方法

5.1 for循环

for(int i = 0; i < list.size(); i++){
    ...
}

5.2 foreach

foreach(int n : list){
    ...
}

5.3 Iterator迭代器

Iterator it = list.iterator();
while(it.hasNext()){
    object o = it.next();
    ...
}

6. 主要实现类的区别总结

6.1 HashMap 和 Hashtable 区别

线程安全

Hashtable 是线程安全的,HashMap 不是线程安全的。
Hashtable 所有的元素操作都是 synchronized 修饰的,而 HashMap 并没有

性能优劣

由于Hashtable是线程安全的,所以每个方法都要阻塞其他线程,导致Hashtable性能较差,而HashMap性能较好。
若需要线程安全又保证性能,可以使用 JUC 包下的 ConcurrentHashMap

允许NULL

Hashtable 是不允许键或值为 null 的,HashMap 的键值则都可以为 null。

实现方式

这里看一下HashMap和Hashtable的类定义就清楚了:
HashMap 的继承源码:

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable

Hashtable 的继承源码:

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable,java.io.Serializable

容量扩容

HashMap 的初始容量为:16,Hashtable 初始容量为:11,两者的负载因子默认都是:0.75。

迭代器

HashMap 中的 Iterator 迭代器是 fail-fast 的,而 Hashtable 的 Enumerator 不是 fail-fast 的。

所以,当其他线程改变了HashMap 的结构,如:增加、删除元素,将会抛出 ConcurrentModificationException 异常,而 Hashtable 则不会。

6.2 Vector 和 ArrayList 区别

线程安全

Vector是线程同步的,所以它也是线程安全的,而ArrayList是线程异步的,是不安全的。如果不考虑到线程的安全因素,一般用ArrayList效率比较高。

扩容值

如果集合中的元素的数目大于目前集合数组的长度时,Vector增长率为目前数组长度的100%,而ArrayList增长率为目前数组长度的50%。如果在集合中使用数据量比较大的数据,用Vector有一定的优势。

性能

ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要涉及到数组元素移动等内存操作,所以索引数据快,插入数据慢,Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差,LinkedList使用双向链表实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。







[参考书籍]:《Java编程思想》
参考博文:集合大家族
参考博文:java集合详解和集合面试题目

集合类优秀博文连接1
集合类优秀博文连接2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值