集合
集合
- 概述:用来存储多个数据的容器。
- 集合和数组的区别:
共同点:
都是用来存储数据的容器,都可以存储多个数据
不同点:
(1)数组的大小是固定的,不能新增也不能减少元素;集合的大小是可以进行改变的,可以往集合中新增元素或者删除元素。
(2)数组既可以存储基本数据类型的数据,也可以存储引用数据类型的数据;集合只能存储引用数据类型数据。
(3)数组中本身操作元素的功能比较少,就只有一个length属性;集合的功能比较多,有很多以操作元素的方法。
3、使用集合的原因:
(1)数组的大小不能伸缩,如果需要增加或者删除元素,操作起来比较麻烦集合可以直接增加或者删除元素,操作起来比较容易
(2)数据中操作元素的功能比较少,集合可以有很多方法操作元素
集合的体系
Collection集合
Collection集合
- 单词:收集,集合
- 概述:此类是单列集合的顶层接口,任何单列集合都属于该接口的子接口或者实现类。
- 特点:
(1)是一个接口不能去创建对象。只能通过实现类创建对象访问其中的方法。
(2)在java.util包,需要导包使用
(3)Collection中定义的方法,子接口和实现类都可以去使用。
Collection 集合的常用方法
- add(E e) :往集合中添加元素
- addAll(Collection<? extends E> c) :将集合c中的内容全添加到调用者集合中
- remove(Object o) :删除集合中的o元素
- removeAll(Collection<?> c) :删除调用者集合中和c集合中相同的元素
- clear() :清空集合
- contains(Object o) :判断集合中是否包含元素o
- containsAll(Collection<?> c) :判断调用者集合中是否全部包含集合c的所有元素
- isEmpty() :判断集合是否为空
- size() :返回集合中元素的个数
Collection集合的第一种遍历方式
- 方式:转数组遍历:将集合通过某个方法转为一个数组,再遍历数组,间接的遍历集合
- 集合转为数组的方法:toArray()
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("abc");
c.add("xyz");
c.add("123");
Object[] os = c.toArray();
for (int i = 0; i < os.length; i++) {
System.out.println(os[i]);
}
}
Collection集合的第二种遍历方式
- 方式:使用迭代器遍历集合
迭代:更新换代,一个到下一个的过程
迭代器:就是遍历集合的对象。 - 获取迭代器的方式:通过集合定义的方法来获取:iterator()
- 迭代器对象可以使用的方法:
next();
hasNext();
remove(); - 注意事项:
1、使用next方法可以获取集合中的所有元素,虽然反复使用的方法是一样的,但是返回的数据不同。
2、next方法不仅可以获取元素,还可以移动指针,获取一次之后,指针指向下一个元素。
3、如果没有下一个元素,仍然获取出现java.util.NoSuchElementException(没有当前元素异常)。
4、可以使用hasnext方法来判断集合中指针指向的当前元素是否存在
5、反复使用next和hasnext方法比较麻烦,所以使用while循环来简化操作。
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("abc");
c.add("xyz");
c.add("123");
Iterator it = c.iterator();
while(it.hasNext()) {
Object o = it.next();
System.out.println(o);
}
}
Collection集合的第三种遍历方式
- 方式:使用增强for循环遍历
- 增强for循环:
(1)它是JDK5之后出现的,其内部原理是一个Iterator迭代器
(2)实现Iterable接口的类才可以使用迭代器和增强for循环完成数组和Collection集合的遍历 - 格式:
for(元素的数据类型 元素名称:集合或者数组名称){
元素名称的使用
}
说明:
1、元素的数据类型:集合或者数组中元素的类型
2、元素名称:给集合或者数组中的每一个元素起的一个合法的表示符
3、集合或者数组名称:要遍历的数组或者集合名称
public static void main(String[] args) {
Collection c = new ArrayList();
c.add("abc");
c.add("xyz");
c.add("123");
for(Object o : c) {
System.out.println(o);
}
}
List集合
List集合
- 概述:List集合是Collection接口下的子接口
- 特点:
(1)属于一个单列集合
(2)List也是一个接口,不能直接创建对象
(3)该集合中的元素特点:
有序:元素存入的和取出的顺序可以保证一致
有索引:每个元素都有自己的一个位置,通过有序的序号来表示这个位置,索引范围:0—集合长度-1
可重复:集合中可以存储相同的元素值
List 集合特殊的方法
- add(int index, E element) :往集合中的指定位置添加元素
- get(int index) :获取集合中指定元素的值
- remove(int index) :删除指定位置的元素
- set(int index, E element) :修改集合中指定位置的元素值为ele
并发修改异常
- ConcurrentModificationException
并发 修改 异常 - 原因:
使用迭代器对象遍历集合的同时,使用了集合对象增加或者删除元素 - 解决:
使用集合对象遍历,使用集合对象增加元素
使用迭代器对象遍历,使用迭代器对象增加元素 - 使用集合对象遍历,使用集合增加
使用list集合特有的方式遍历
使用集合中的add或者remove方法增加或者删除
5、使用迭代器遍历,使用迭代器增加
(1)iterator()方法获取迭代器对象中只能使用删除方法,不能使用增加方法
(2)如果需要使用迭代器对象增加元素,可以使用List集合特有的方式来获取迭代器对象:
获取方式:listIterator()
add(E e) 添加元素
remove() 移除元素
数据结构总结
- 栈
栈概述:stack,又称堆栈,它是运算受限的线性表,其限制是仅允许在标的一端进行插入和删除操作,不允许在其他任何位置进行添加、查找、删除等操作。
特点: 先进后出,(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。
例如:子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。
相关概念:
压栈:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置。
弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置。
图示:
- 队列
概述:queue,简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。
特点:- 先进先出(即,先存入元素先取出,后存入的元素后取出)。
例如,小火车过山洞,车头先进去,车尾后进去;车头先出来,车尾后出来。 - 队列的入口、出口各占一侧。
图示:
- 先进先出(即,先存入元素先取出,后存入的元素后取出)。
- 数组
Array:是有序的元素序列,数组是在内存中开辟一段连续的空间,并在此空间存放元素。
特点:
(1)查找元素快:可以通过指定的索引快速查询当前元素所在的位置,并访问元素因为只需要通过要访问的索引,计算地址即可,通过计算之后的地址,就可以直接找到要查询的元素
(2)增删元素慢:
如果需要增加一个元素,就会重新新建一个容量+1的数组,将数组中的元素复制到新数组中,再将需要添加的元素添加到指定位置。
如果需要删除一个元素,就重新新建一个容量为-1的数组,将不删除的其他元素复制到新数组中。 - 链表
链表:linkedlist,由一系列结点node(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
组成及分类:
(1)每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储上一个节点或者下一个结点地址的指针域。
(2)双向链表就是既可以存储上一个节点也可以存储下一个节点的链表
(3)单向链表是只可以存储下一个节点的链表
图示:
特点:
(1)查找元素慢:想查找某个元素,需要通过开始连接的节点,依次向后查找指定的元素
图示:
(2)增删元素快:
增加元素只需要修改上一个节点的地址为新节点的地址即可
删除元素只需要修改上一个节点的地址即可
List的实现类
- 概述:List集合也是一个接口,根据底层存储数据方式的不同有不同的实现类
- 分类:
ArrayList
LinkedList
ArrayList
- List集合的实现类,本类没有特殊的方法,只能使用接口中定义的方法
- 特点:
(1)底层数组实现,可以表示元素有序,底层是通过数组来实现的,通过数组空间的连续来表示元素的有序
(2)查询元素的效率高,增删元素的效率低 - 总结:
(1)创建一个集合对象,其实就是创建了一个数组
(2)如果需要增加元素:
先判断维护的数组空间是否够用,如果不够用,将空间扩充为原来的1.5倍扩充之后,将老数组中的元素,赋值到新数组中,在指定位置或者在后面添加新元素
(3)如果需要删除元素:
①如果删除某个索引对应的元素,先判断索引是否越界,越界则抛出索引越界异常,不越界,就删除移除索引对应的元素,将后面的元素往前移动
②如果要删除某一个元素,通过遍历数组,查询相同的值,相同就删除,删除之后,后面的元素往前移动。
LinkedList
-
属于List接口的实现类,可以使用接口中继承方法
-
特点:
(1)底层通过双向链表实现,可以保证元素有序
(2)查询元素效率低,增删元素效率高 -
特有方法:因为linkedList可以记录头部和尾部元素的地址,所以有一些操作头部和尾部元素的方法:
addFirst(); 在头部位置添加元素
addLast(); 在尾部添加元素
removeFirst(); 删除头部位置的元素
removeLast(); 删除尾部的元素
getFirst(); 获取头部元素
getLast(); 获取尾部元素
pop(); 移除集合的第一个元素并回去该元素
push(E e); 将指定元素添加到集合的第一个元素中