集合
类名:collection类是一个接口。collections是集合工具类。
第一阶段:
封装继承多态集合反射
概念
对象的容器,存储对象的对象,可替代数组(数组的长度固定弊 端)。(只能存储对象)
特点
容器的工具类,定义了对多个对象进行操作的常用方法。
位置
java.util.*
集合类的主要架构
List接口
List接口,有序序列,有序集合。
ArrayList类
ArrayList实现接口List,List接口实现Collect接口。
可调整大小的数组的实现List接口,除了实现List 接口
之外,该类还提供了一些方法来操纵内部使用的存储列表的数组的大小,这个类是大致相当于Vector
不同之处在于它是不同步的(线程不安全)。
泛型:用于统一集合中的数据类型。
基本使用
构造方法
ArrayList() 无参构造
方法
add()
作用:添加元素,默认添加在末尾。在指定位置添加元素。
参数:object 或 index,object;
当传入一个对象时,默认添加在末尾;
当传入一个index和obj时,会在指定下标处添加元素obj;
返回值:布尔值或无
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
set(int index, E element)
作用:用指定的元素替换此列表中指定位置的元素。
参数:下标index和元素
返回值:返回之前对应下标的老元素
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 修改指定下标元素
Object res1 = arrlist.set(1, "xiaoyu");
System.out.println("res1 = " + res1); // 返回老元素
get(int index)
作用:返回此列表中指定位置的元素
参数:集合内的下标index
返回值:对应下标集合内的元素
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 获取元素
Object res2 = arrlist.get(0);
System.out.println("res2 = " + res2); // 返回元素
size()
作用:返回此列表中的元素数
参数:无;
返回值:int类型;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 获取元素数量
int size = arrlist.size();
System.out.println("size = " + size);
E remove(int index)
作用:删除集合内的元素
参数:object或下标,
当传入object时,从前往后匹配,删除第一个匹配到的元素;
当传入下标index时,删除指定下标的元素;
返回值:
当传入obj类型时,返回值类型是布尔类型,是否删除成功;
当传入是下标时,返回值是删除的元素本身;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 删除元素
boolean res3 = arrlist.remove(44.5);
System.out.println("res3 = " + res3);
// 删除元素
Object res4 = arrlist.remove(1);
System.out.println("res3 = " + res4);
contains(Object o)
作用:集合中是否包含指定的元素
参数:传入object元素;
返回值: 存在则返回true,否则为false;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
boolean res1 = arrlist.contains("sakuna");
System.out.println("res1 = " + res1); // true
clear()
作用:从集合中删除所有元素;
参数:无;
返回值: 无;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 删除所有元素
arrlist.clear();
indexOf(Object o)
作用:返回指定元素的在集合中第一次出现的索引,如果此列表不包含元素,则返回-1;
参数:obj元素;
返回值:int类型或-1;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 返回第一次出现的位置
int index = arrlist.indexOf(44.5);
System.out.println("index = " + index); // 0
isEmpty()
作用:集合是否为空;
参数:无;
返回值:布尔值;
示例:
// 创建ArrayList对象
ArrayList arrlist = new ArrayList();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
arrlist.add(0,44.5);
// 返回第一次出现的位置
boolean empty = arrlist.isEmpty();
System.out.println("empty = " + empty);
iterator():ArrayList类中的Iterator方法实现了List接口中的接口抽象方法,List接口实现了Iterator抽象类中的方法。
作用:迭代器遍历元素;
参数:无;
返回值:迭代器Iterator对象;
示例:
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 创建迭代器对象
Iterator<String> iterator = arrlist.iterator();
集合遍历
对于ArrayList而言,底层为数组。
方式1:普通for循环遍历
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 遍历元素
for (int i = 0; i < arrlist.size(); i++) {
System.out.println("item" + i + " = " + arrlist.get(i));
}
方式2:迭代器遍历
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 迭代器遍历
// 创建迭代器对象
Iterator<String> iterator = arrlist.iterator();
// 使用迭代器类中的实例方法 iterator.hasNext() 判断当前迭代器对象中是否还有元素
while (iterator.hasNext()){
System.out.println(iterator.next());
}
方式3:增强for循环:底层实现还是迭代器,JDK1.5新增内容,属于对迭代器书写格式的简化。
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 增强for循环
for (String str : arrlist) {
System.out.println("str = " + str);
}
增强for遍历
idea快捷键:元素名称.for
增强for循环:可以遍历数组,遍历集合。底层实现还是迭代器,JDK1.5新增内容,属于对迭代器书写格式的简化。
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 增强for循环
for (String str : arrlist) {
System.out.println("str = " + str);
}
集合特点
- 有序,空间连续(默认顺序是元素插入顺序);
- 有下标
- 允许重复
- 允许null元素
- 线程不安全
数据结构
ArrayList的数据结构是数组。
源码解析
通常在Java中把某个对象的引用置为null,就可以等着Java中的gc等着回收空间。
1、 调用ArrayList无参构造的时候,在底层维护了一个长度为0的数组。
2、调用ArrayList中的add方法时,才将数组的长度改为10,当集合空间不够时,扩容集合空间,默认扩容为原有空间的1.5倍空间。
3、 增删改查效率问题
增删改查效率:查询 和 修改 快
添加如果需要扩容的、插入元素的情况 效率较低 因为需要复制数组 或者 移动元素
删除需要移动元素的情况 效率低
迭代器类
Iterator类
迭代器是无法保证顺序,集合中的元素将原封不动的保存在迭代器对象中。
迭代器是没有下标概念的,每次遍历先查询迭代器对象中还有没有元素,如果有则取出(返回元素),然后继续遍历。没有则返回null。
迭代器遍历的过程
遍历之前游标指针默认指向空;
当调用了 hasNext() 方法之后,指针就会向后移动一位,同时把这个元素从迭代器对象中删除;
也就是永远也无法再迭代器对象中找到这个返回的数据了。
方法
hasNext()
作用:如果迭代具有更多元素,则返回 true,否则返回false;
参数:无;
返回值:布尔类型;
示例:
Iterator<String> iterator = arrlist.iterator();
boolean b = iterator.hasNext();
next()
作用:返回迭代中的下一个 元素;
参数:无;
返回值:Object;
示例:
// 创建ArrayList对象,同时设置泛型
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 迭代器遍历
// 创建迭代器对象
Iterator<String> iterator = arrlist.iterator();
String next = iterator.next();
System.out.println("next = " + next); // next = sakuna
泛型
泛型:用于统一集合中的数据类型。
// 创建ArrayList对象,同时设置泛型 String
ArrayList<String> arrlist = new ArrayList<String>();
// add 方法 实例级别
boolean res = arrlist.add("sakuna");
// 在指定位置插入元素
// arrlist.add(0,44.5); // 报错,因为泛型为 String,集合内的元素对象类型必须是 String
arrlist.add("春绯小语");
// 遍历元素
for (int i = 0; i < arrlist.size(); i++) {
System.out.println("item" + i + " = " + arrlist.get(i));
}
Vector类
基本使用
构造函数
初始容量为10,扩容容量默认为2倍,可通过构造函数指定扩容倍数。
无参构造
Vector()
有参构造
Vector(int initialCapacity, int capacityIncrement)
构造具有指定初始容量和容量增量
方法: 此类中拥有的方法和ArrayList类中的方法是一样的。
add()
作用:添加元素,默认添加在末尾。在指定位置添加元素。
参数:object 或 index,object;
当传入一个对象时,默认添加在末尾;
当传入一个index和obj时,会在指定下标处添加元素obj;
返回值:布尔值或无
示例:
// 创建ArrayList对象
Vector vector = new Vector();
// add 方法 实例级别
boolean res1 = vector.add("sakuna is kawaii");
// 在指定位置插入元素
vector.add(1,"yousa");
...
集合遍历
集合遍历的方式和ArrayList类中方式相同。
方式1:
// 普通for循环遍历
for (int i = 0; i < vector.size(); i++) {
Object item = vector.get(i);
System.out.println("item = " + item);
}
方式2:
// 迭代器遍历
Iterator iterator = vector.iterator();
while (iterator.hasNext()){
Object item = iterator.next();
System.out.println("item = " + item);
}
方式3:
// 增强for遍历
for (Object item : vector) {
System.out.println("item = " + item);
}
面试题
ArrayList类和Vector类的区别?
1、ArrayList线程不安全,Vector线程安全;
2、ArrayList无参构造维护长度为0空数组,Vector无参构造维护长度为10的数组;
3、ArrayList默认扩容1.5倍,Vector扩容2倍;
4、ArrayList不允许指定增量,Vector可以指定增量;
StringBuffer和StringBuilder的区别
StringBuffer 线程安全
StringBuilder 线程不安全
源码解析
1、调用构造,创建对象时,代码执行过程。
2、 添加元素的时候,代码执行过程。
3、删除元素时,代码执行过程。
LinkedList类
如同生活中的链子一样,实现了List接口,同时实现了Deque(队列)接口,他有列表的功能,同时拥有数组功能。
基本使用
构造方法
// 构造一个空列表
LinkedList()
// 构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序
LinkedList(Collection<? extends E> c)
方法: 除了拥有ArrayList类相同的方法以外,还单独拥有操作头部和尾部的方法。
add()
作用:添加元素,默认添加在末尾。在指定位置添加元素。
参数:object 或 index,object;
当传入一个对象时,默认添加在末尾;
当传入一个index和obj时,会在指定下标处添加元素obj;
返回值:布尔值或无
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
...
remove():这个方法和ArrayList中的remove有些许差别,他支持无参删除
作用:删除集合内的元素
参数:object或下标或无
当传入object时,从前往后匹配,删除第一个匹配到的元素;
当传入下标index时,删除指定下标的元素;
当无参时,默认删除第一个元素;
返回值:
当传入obj类型时,返回值类型是布尔类型,是否删除成功;
当传入是下标时,返回值是删除的元素本身;
当无参时,返回删除元素本身;
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
Object rmItem = linkedList.remove(); // sakuna
Object rmItem2 = linkedList.remove(1); // Hikari
System.out.println("rmItem = " + rmItem);
addFirst()
作用:在链表的头部添加元素
参数:object元素
返回值:无
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
addLast()
作用:在链表的尾部添加元素
参数:object
返回值:无
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
// 在链表的末尾添加元素
linkedList.addLast("Reine");
getFirst()
作用:获取链表的第一个元素
参数:无;
返回值:Object元素;
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
linkedList.addLast("Reine");
// 获取列表的首个元素
Object firstItem = linkedList.getFirst();
System.out.println("firstItem = " + firstItem);
getLast()
作用:获取链表的最后一个元素
参数:无;
返回值:Object元素;
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
linkedList.addLast("Reine");
// 获取列表的首个元素
Object firstItem = linkedList.getFirst();
Object lastItem = linkedList.getLast();
System.out.println("firstItem = " + firstItem);
System.out.println("lastItem = " + lastItem);
removeFirst()
作用:删除集合内的第一个元素
参数:无
返回值:删除的元素本身
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
linkedList.addLast("Reine");
// 删除第一个元素
Object rmFirstItem = linkedList.removeFirst();
System.out.println("rmFirstItem = " + rmFirstItem); // rmFirstItem = charl
removeLast()
作用:删除集合内的最后一个元素
参数:无
返回值:删除的元素本身
示例:
LinkedList linkedList = new LinkedList();
boolean res = linkedList.add("sakuna");
linkedList.add(1,"yousa");
linkedList.add(2,"Hikari");
linkedList.addFirst("charl");
linkedList.addLast("Reine");
// 删除第一个元素
Object rmFirstItem = linkedList.removeFirst();
System.out.println("rmFirstItem = " + rmFirstItem); // rmFirstItem = charl
// 删除最后一个元素
Object rmLastItem = linkedList.removeLast();
System.out.println("rmLastItem = " + rmLastItem); // rmLastItem = Reine
集合遍历
遍历如同ArrayList集合遍历方式
方式1:for循环(一次一次的查询获取到数据),越往后查询越慢,因为空间不连续,需要先查找相邻的元素,才能找到指定元素。而ArrayList底层使用的是数组,可以一次查询到对应元素,所以ArrayList类中for循环比较快。
// 普通for循环遍历
for (int i = 0; i < linkedList.size(); i++) {
Object item = linkedList.get(i);
System.out.println("item = " + item);
}
方式2:迭代器遍历(直接下一个返回数据,效率要高于for循环遍历)
// 迭代器遍历
Iterator iterator = linkedList.iterator();
while (iterator.hasNext()){
Object item = iterator.next();
System.out.println("item = " + item);
}
方式3:增强for循环遍历(底层使用的仍是迭代器)
// 增强for遍历
for (Object item : linkedList) {
System.out.println("item = " + item);
}
不推荐普通方式遍历 LinkedList集合
集合特点
有序,空间不连续,可以利用碎片空间;
有下标;
可以重复;
允许null元素;
线程不安全;
空间不连续示 意图:
在内存物理空间上不连续,但是还是有顺序的。
数据结构
LinkedList类中的每个元素(Node)的特点。
LinkedList的数据结构是双向链表。
不需要扩容;
删除,添加元素不需要移动元素;
查询,修改(也需要先查询)元素效率低,因为必须要先找到相邻元素位置,才能找到对应元素;
新增元素默认在末尾添加元素;
双向链表
数据结构:双向链表 没有初始大小 没有上限大小 不需要扩容
源码定义:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element; // 当前元素内容
this.next = next; // 指向后一个元素地址
this.prev = prev; // 指向前一个元素地址
}
}
源码解析
1、调用构造,创建对象时,代码执行过程。
2、 添加元素的时候,默认添加元素到末尾,代码执行过程。
3、删除元素时,代码执行过程,需要先查询元素(这里做了优化,设置长度中间值,大于中间值从后往前,小于中间值从前往后)
删除过程
4、修改元素时,代码执行过程。