![75f9fa5a7e59aba48b9b99e437dd70fe.png](https://i-blog.csdnimg.cn/blog_migrate/d6dcbb1ba0c9c1d9bbdf394f39aa76a1.jpeg)
集合
1. 为什么要使用集合框架?
传统的容器(数组)在进行增、删等破坏性操作时,需要移动元素,可能导致性能问题;同时添加、删除等算法和具体业务耦合在一起,增加了程序开发的复杂度。
Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中。
2. Collection
Collection是java集合框架(collection-frame)中的顶层接口。
Collection接口是一个容器,容器中只能存储引用数据类型,建议存同一类型的引用类型,方便后续遍历等操作。
容器中的元素可以是有序的、可重复的,称为List接口。
也可能是无序的、不可重复(唯一)的,称为Set接口。
![38e6227d9f0399d7179378ab69621d9f.png](https://i-blog.csdnimg.cn/blog_migrate/9ba84bf0380656edfaf4a0da7a48e570.jpeg)
2.1 集合常用方法
public
2.2 集合的遍历
Iterable 可遍历的接口,集合接口继承于它,集合支持快速遍历。
// 快速遍历
快速遍历的本质:Collection继承Iterable接口,表示集合支持快速遍历。Iterable接口定义了一个方法iterator()用于获取集合的迭代器,是一个Iterator接口类型,iterator()内部返回一个实现类实现Iterator接口。这个实现类一定具有hasNext和next方法用于判断是否有下一个元素和获取下一个元素。快速遍历就是基于迭代器工作的。
public
![a5b54947c7578296adad321dc216a1a5.png](https://i-blog.csdnimg.cn/blog_migrate/e0a2e40cd7222c9b7b52058b7433da0b.jpeg)
3. List接口
List 接口中的元素时有序的、可重复的。List接口中的元素通过索引(index)来确定元素的顺序。
有序的 collection(也称为序列)。可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
3.1 list常用方法
public
3.2 List接口遍历
ListIterator 继承于Iterator,在Iterator的基础上提供了以正向遍历集合,也可以以逆序遍历集合。
hasNext/next 以正向遍历。
hasPrevious/previous 以逆序遍历。
public
![44a18ee1dd7b33c14fe669e39016fd9f.png](https://i-blog.csdnimg.cn/blog_migrate/503cf4310c6fefd679ef542129886f57.jpeg)
4. 数据结构
数据结构就是数据在内存中存储结构。根据存储的方式不同,分为线性表、二叉树、图、栈、队列等
4.1 线性表
线性表数据按照一定的逻辑顺序存储在内存中。线性表是有序的。线性表根据内存的物理结构分为两种:数组和链表
数组是一种逻辑上有序的线性表,物理上也连续。
![62ba6dc53caf4347f60bbf2e7d02b4cf.png](https://i-blog.csdnimg.cn/blog_migrate/af98a18184861569d566151d3db3751d.jpeg)
链表是一种逻辑上有序的线性表,但物理上不连续。
![aa13c2065f09a58c2b7424992115d6ee.png](https://i-blog.csdnimg.cn/blog_migrate/9a7360f0401701e5936583f53712628a.jpeg)
数组和链表的区别
相同点:在逻辑上是有序的。
不同点:1.数组在查询时效率高,在添加、删除元素时效率低(涉及移动元素) 2.链表在查询时效率低(每次从头开始,不能跳跃访问),在添加、删除元素时效率高(不涉及移动元素)
4.2 栈
特性:先进后出,后进先出(就像子弹夹中的子弹)
![aba24ca9883009bdfa779f0688e6f80c.png](https://i-blog.csdnimg.cn/blog_migrate/90e03fd8ade2ff3f8cfe05eb6105ae85.jpeg)
4.3 队列
特性:先进先出
![70c53c33a3dcdfd3170045970f405d9f.png](https://i-blog.csdnimg.cn/blog_migrate/1d73d463928d317d12ef188be97e5934.jpeg)
5. ArrayList/Vector
ArrayList 是List接口的实现类,底层数据结构是数组,实现大小可变的数组。
ArrayList 线程不安全,jdk1.2开始。
ArrayList 底层数据结构是数组,默认数组大小是10,如果添加的元素个数超过默认容量,ArrayList会自动拓容,拓容原则:newCapacity = oldCapacity + oldCapacity / 2;
如果未来确定序列的元素不在增加,通过调用trimToSize()调制容量至合适的空间。
ArrayList作为List接口的实现类,常用方法和遍历方法参考List接口。
Vector 是List接口的实现类,底层数据结构也是数组,也是大小可变的数组。
Vector是线程安全的,jdk1.0开始。
Vector底层数据结构是数组,默认数组大小是10,如果添加的元素个数超过默认容量,Vector会自动拓容,拓容原则:newCapacity = oldCapacity +capacityIncrement(增长因子);如果未来确定序列的元素不在增加,通过调用trimToSize()调制容量至合适的空间。
注意:Vector 在实现List接口的同时,添加了自身特有的方法xxxElement,未来使用时为了程序的可拓展性,一定要按照接口来操作Vector。
6. LinkedList
LinkedList是List接口的实现类,底层数据结构是链表。
LinekList常用方法和遍历方法参照List接口。
LinkedList 线程不安全。
除了实现List接口, 还实现栈接口。
![f98beda782c3c7325b712052ccba95ab.png](https://i-blog.csdnimg.cn/blog_migrate/6c4edf69aae89ab6907259ba8d93c3a4.png)
push入栈操作 / pop出栈操作
public
队列(Queue)接口
![fe063957a11402a0eea339856c81a221.png](https://i-blog.csdnimg.cn/blog_migrate/b6ea79dbfa38b777ff8b5080a6ac64c6.jpeg)
add/remove/element() 可能会出现NoSuchElementException异常
public
offer/poll/peek 可能会返回特殊值(null)
public
双向队列(Deque)接口
![9931e03c7a47c785dd680872fd53b5ab.png](https://i-blog.csdnimg.cn/blog_migrate/a2f6d2292822f5858d2271bf2787fc83.jpeg)
/**
7. Iterator和ListIterator
Iterator在迭代过程中不允许向集合中添加元素。
public
当通过Iterator集合迭代器遍历集合过程中,不能再向集合汇总添加元素,否则出现ConcurrentModificationException 并发修改异常。
ListIterator允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置
public
8. 泛型(generic)
8.1泛型的概念
泛型允许开发者在强类型程序设计语言(java)编写代码时定义一些可变部分,这些部分在使用前必须作出指明。
泛型就是将类型参数化
ArrayList<E> list表示声明了一个列表list,列表的元素是E类型
ArrayList<String> list = new ArrayList<String>();
声明了一个列表list,列表的元素只能是String类型。
8.2 泛型的擦除
泛型在运行时已经被擦除了。
public
Cannot perform instanceof check against parameterized type ArrayList<String>. Use the form ArrayList<?> instead since further generic type information will be erased at runtime(无法对参数化类型ArrayList<String>执行instanceof检查。使用ArrayList<?>,因为更多的泛型类型信息将在运行时被删除)
8.3 泛型的应用
8.3.1 泛型类
当一个类中属性的数据类型不确定时,具体是什么类型由使用者来确定时,使用泛型。泛型类的形式
public
定义一个泛型类
public
public
8.3.2 泛型方法
当一个方法的参数类型不确定时,具体是什么类型由使用者来确定,可以考虑使用泛型方法。形式。
public
public
public
泛型方法在调用时确定(指明)类型。
泛型方法在一定程度上优化了方法重载。
泛型方法可以定义多个泛型类型。
// 可以定义多个泛型的类型
多个泛型类型进一步优化了方法重载。
多个同类型的泛型
// 多个同类型的泛型
A… a 表示方法可以接受多个参数。当调用方法传递多个参数时,多个参数被放到a数组中,a是什么类型的数组由开发者调用处传参决定。
stu
print(A...a) 方法称为可变参数的泛型形式。