12-集合
1.集合概述
1.集合的由来:
Java语言是一门面向对象的编程语言,所以我们的业务需求大多数都是针对对象的一系列操作,并且操作多个对象。为了方便我们操作,所以我们需要一个容器来存储这些对象。
目前我们学过的容器有哪些?
-
StringBuffer(StringBuilder):它只能存储字符串
-
数组:可以存储对象。但是数组的长度是固定的,并且只能存储单一类型的对象。
但是这两个容器不能满足我们日常开发的需求。Java又给我们提供了另一个容器,这个容器
就叫做集合。
2. 集合 和 数组 的区别
1.长度的区别:
数组的长度是固定
集合的长度是可变
-
存储的区别:
数组元素必须是用一种数据类型。
集合元素 可以是不同类型的元素。
- 存储元素数据类型的区别
数组可以存储基本数据类型,也可以存储引用数据类型。
集合只能存储引用数据类型。
3. 集合的继承体系结构
在生产环境中,对于对象的操作是多种多样。
比如 和 数据结构 有关的
-
有序 , 无序
-
可重复,不可重复
对于对象的一些通用操作。
-
获取元素
-
判断
……
-
为了方便使用,Java根据这些共性内容,不断的向上提取,最终形成了集合的继承体系结构。
4.Collection常用方法
Collection方法:
* 1. 添加功能
* boolean add(Object obj): 添加一个元素
* boolean addAll(Collection c) :添加一个集合元素
* 2.删除功能
* void clear(): 删除所有元素
* boolean remove(Object o): 删除指定元素
* boolean removeAll(Collection c) 删除指定集合中的元素
* 3.判断功能
* boolean contains(Object o) 判断集合中是否包含指定元素
* boolean containsAll(Collection c) 判断集合中是否包含指定的集合元素(是全部包含还是部分?)
* boolean isEmpty(): 判断集合是否为空
* 4. 迭代器
* Iterator<E> iterator()
*
* 5.长度
* int size():获取集合中元素的个数
*
* 6.求交集
* boolean retainAll(Collection c)
*
* 7. 集合转换为数组
* Object[] toArray()
5. 迭代器为什么定义的是一个接口,而不是一个类呢?
因为我们集合的存储结构是多种的,所以对于集合的遍历也应该是有所不同的。定义成接口的好处,就是它可以根据实际需求去具体的实现相应的功能。这应比较灵活。
在遍历集合时,我们需要获取元素,所以,遍历应该包含获取功能。另外,因为集合的长度是可变的。所以为了安全起见,在每次获取元素之前应该进行判断,判断是否还有元素可以取出。所以,遍历应该还具备另一个功能,就是判断功能。所以在定义迭代器时,将这两个方法提取出来,并不给具体的实现。
思考:具体实现应该在哪里呢?
在子类中实现,并且,因为遍历这个功能实际上包含了多个方法,而且我们知道方法之间不能嵌套。所以它的实现应该是在子类的内部类中实现。
迭代器源码:
public interface Iterator{
public abstract boolean hasNext();
public abstract Object next();
}
public interface Iterable<T>{
Iterator iterator();
}
public interface Collection<E> extends Iterable<E> {
Iterator<E> iterator();
}
public class ArrayList{
public Iterator<E> iterator() {
return new Itr();
}
private class Itr{
boolean hasNext();
Object next();
}
}
2.List集合
1.概述
List是一个有序的并且允许元素重复的集合,用户可以通过此几口对集合中的每个元素的插入位置进行精确的控制(索引。)
2.特有功能
* 1.添加功能
* void add( int index, Object element) 在指定索引处添加元素
*
* 2.获取功能
* Object get(int index) 返回列表中指定位置的元素。
* int size()返回列表中的元素数
*
* 3.列表迭代器
* ListIterator<E> listIterator()返回此列表元素的列表迭代器。
*
* 4.修改功能
* Object set(int index , Object element)用指定元素替换列表中指定位置的元素
* 返回值Object是被覆盖的元素
*
* 5.删除功能
* Object remove(int index)移除列表中指定位置的元素
* 返回值Object是被删除的元素
*
* 6.截取功能
* List<E> subList(int start , int end):从指定位置start开始截取到end位置结束。
* 包含start 不包含end
*
3.并发修改异常
* ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
* 分析:迭代器是依赖于集合而存在的。通过集合对象获取迭代器对象之后,我们进行了判断,判断成功后,向集合添加了
* 新的元素。但是,这个添加的行为,是在获取了迭代器之后执行的。所以迭代器并不知道集合发生了改变,所以就
* 差生了并发修改异常
* 解决方案:
* 1.使用迭代器添加元素
* 2.不用迭代器。(普通for循环)
4.常见数据结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oLi0rCfW-1629777184827)(.\img\栈和队列.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hrHQHDq5-1629777184830)(.\img\数组和链表.jpg)]
5.List集合的三个子类
ArrayList : 1.底层实现是数组 。数组的特点:查询快,增删慢
2.线程不同步(不安全):效率高
**Vector:**1.底层实现是数组 。数组的特点:查询快,增删慢
2.线程同步(安全):效率低
**LinkedList:**1.底层实现是链表结构,链表结构的特点:查询慢,增删快
2.线程不同步(不安全):效率高
**面试题:**开发过程中如果你要使用集合,你会根据什么来选择使用不同的集合?
答:首先考虑你是需要效率高 ,还是需要安全性高?
如果安全性要求比较高:选择Vector
如果是考虑效率:
a:查询多 ArrayList
**LinkedList:**1.底层实现是链表结构,链表结构的特点:查询慢,增删快
2.线程不同步(不安全):效率高
**面试题:**开发过程中如果你要使用集合,你会根据什么来选择使用不同的集合?
答:首先考虑你是需要效率高 ,还是需要安全性高?
如果安全性要求比较高:选择Vector
如果是考虑效率:
a:查询多 ArrayList
b:增删多 LinkedList