Java基础系列文章-集合框架体系
Java基础系列文章-集合框架体系
文章目录
前言
提示:这篇文章是笔者Java基础系列文章中的集合体系,下图是集合体系架构图
一、什么是集合
集合是指具有某种特定性质的具体的或抽象的对象汇总而成的集体。
Java提供了一套继承Collection接口和Map接口的标准集合类。其中的一些是具体类,这些类可以直接拿来使用,而另外一些是抽象类,提供了接口的部分实现。
二、为什么要引入集合
数组,集合都是对多个数据进行存储操作的,简称为容器。
PS:这里的存储指的是内存层面的存储,而不是持久化存储(.txt,.avi,.jpg,数据库)。
集合是对数组的封装 ,提供了比数组更多的功能,但是相应的速度就会比数组慢,一些源码会发现很多数组的操作。
PS:笔者觉得不能因为一些性能的损失而去放弃集合强大的功能而去使用数组,现在的硬件性能非常强了。
数组的特点:
- 数组一旦指定了长度,那么长度就被确定了,不可以更改。
int[] arr = new int[8]; - 数组一旦声明了类型以后,数组中只能存放这个类型的数据。数组中只能存放同一种类型的数据。
int[] arr,String[] s,double[] d… - 数组中的元素可以是任何数据类型,包括基本类型和引用类型
- 数组变量属于引用类型,数组也可以看作是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中的对象在堆中,因此数组无论保存原始类型还是其他对象类型,数组本身是在堆中的
数组的缺点:
1. 数组一旦指定了长度,那么长度就被确定了,不可以更改,所以在使用的时候如果所需数据没有超过数组范围就会造成存储空间的浪费 。如果超出下标范围,就会有一个我们常见的异常ArrayIndexOutOfBoundsException(数组下标越界异常)。
3. 删除,增加元素 效率低。
4. 数组中实际元素的数量是没有办法获取的,没有提供对应的方法或者属性来获取 。
5. 数组存储:有序,可重复 ,对于无序的,不可重复的数组不能满足要求。
而正因为数组的这些缺点,引入了新的存储数据的机构,也就是集合。
三、Java中一些集合的介绍
3.1 List集合
有序可以重复,遍历方式:1 普通for 2 增强for 3 迭代器
3.1.1 ArrayList(常用)
底层是Object类型的数组,故优缺点同数组:查询快,增删慢
线程不安全,效率高
源码类似StringBuilder
源码示例:
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
3.1.2 LinkedList
底层是双向链表,查询慢,增删快
线程不安全,效率高
源码示例:
/**
* Returns the (non-null) Node at the specified element index.
*/
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
3.1.3 Vector
底层是数组,查询快,增删慢
线程安全,效率低,基本淘汰
3.2 Set集合
无序不随机不可重复,遍历方式和Collection接口一样是增强for和迭代器方式
3.2.1 HashSet
底层结构:数组+链表(Hash表)
如果放入HashSet的数据,一定要重写hashCode和equles,可以看下面的案例
public class TestStudent {
//这是main方法,程序的入口
public static void main(String[] args) {
//创建一个HashSet集合:
HashSet<Student> wg = new HashSet<>();
wg.add(new Student(19,"wangzi"));
wg.add(new Student(20,"gongzu"));
wg.add(new Student(19,"wangzi"));
System.out.println(wg);
}
}
Student是自定义类型,这样HashSet就不满足无序唯一的特性了
HashSet原理:
集合中存数据,调用对应的hashCode方法计算hash值,然后并通过equles方法判断是否重复,最后通过hash值和表达式计算出在数组中放入的位置。
3.2.2 LinkedHashSet
底层数据结构由链表和哈希表组成。 由链表保证元素有序(按照输入顺序进行输出)。 由哈希表保证元素唯一。
其实就是在HashSet的基础上,多了一个总的链表,这个总链表将放入的元素串在一起,方便有序的遍历
LinkedHashMap.Entry 继承自HashMap.Node 除了Node 本身有的几个属性外,额外增加了before after 用于指向前一个Entry 后一个Entry。也就是说,元素之间维持着一条总的链表数据结构。
3.2.3 TreeSet
唯一,无序(没有按照输入顺序进行输出), 有序(按照升序进行遍历)
数据结构是二叉树,物理结构是跳转结构
TreeSet底层的二叉树的遍历是按照升序的结果出现的,这个升序是靠中序遍历(左 根 右)得到的
TreeSet实现唯一,有序的原理是底层用了内部比较器(让元素所属的类实现Comparable接口),但是为了扩展性更好(多态),而我们常用的也是外部比较器(让集合接收一个Comparator的实现类对象),这样TreeSet进行比较的时候就会使用我们扩展的外部比较器。
3.3 Map集合
双列集合
1 Map集合的数据结构仅仅针对键有效,与值无关。
2 存储的是键值对形式的元素,键唯一,值可重复。
3.3.1 HashMap
无序唯一,底层是hash表,效率高,线程不安全 ,key可以存入null,且唯一。遵循hash表原理:放入集合的数据必须重写hashCode方法和equles方法
3.3.2 LinkedHashMap
链表+hash表
唯一,有序(按输入顺序进行输出)
3.3.3 Hashtable
底层数据结构是哈希表。线程安全,效率低,key不可以存入null
3.3.4 TreeMap
唯一,有序(升序或者降序)
二叉树,放入集合的key的数据对应的类型内部一定要实现比较器(内部比较器,外部比较器)
四、集合的用武之地
最常用的还是HashMap和ArrayList,涉及并发可能会用到ConcurrentHashMap(
JDK5.0之后提供了多种并发类容器可以替代同步类容器,提升性能、吞吐量
ConcurrentHashMap替代HashMap、HashTable
ConcurrentSkipListMap替代TreeMap
特点:
ConcurrentHashMap:性能高,线程安全
Hashtable: 线程安全,性能低
HashMap:线程不安全,性能高
实现线程安全的HashMap:线程安全,性能低
)
是否是键值对象形式:
是:Map
键是否需要排序:
是:TreeMap
否:HashMap
不知道,就使用HashMap。
否:Collection
元素是否唯一:
是:Set
元素是否需要排序:
是:TreeSet
否:HashSet
不知道,就使用HashSet
否:List
要安全吗:
是:Vector(其实我们也不用它,后面我们讲解了多线程以后,我在给你回顾用谁)
否:ArrayList或者LinkedList
增删多:LinkedList
查询多:ArrayList
不知道,就使用ArrayList
不知道,就使用ArrayList
五、集合的常见方法及遍历方式
Collection:
add()
remove()
contains()
iterator()
size()
遍历方式:
增强for
迭代器
|--List
get()
遍历:
普通for
|--Set
Map:
put()
remove()
containskey(),containsValue()
keySet()
get()
value()
entrySet()
size()
遍历方式:
根据键找值
根据键值对对象分别找键和值。
总结
以上就是今天要讲的内容,本文仅仅简单介绍了集合框架体系,还有很多不完善之处请见谅。
著作权归NoLongerConfused所有。商业转载请联系NoLongerConfused获得授权,非商业转载请注明出处。