1 集合继承体系
集合本质上就是一个容器。
数组和集合区别:
1、长度不同:数组的长度是固定的,集合的长度是可变的
2、存储数据(元素)的类型不同:数组可以存储基本数据类型的元素,也可以存储引用数据类型的元素。集合只能存储引用数据类型。
3、数组只能存储同一种数据类型的元素,而集合可以存储多种数据类型的元素
针对不同的存储需求,Java就给我们提供了不同的集合类,而这些集合类之间是存在共性的内容,既然存在共性的内容,就需要向上抽取,最终就形成了一个集合的继承体系图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-20sQcZRK-1634970582735)(images/image-20210426104216483.png)]
上图说明:
- 上图红色标注的表示接口,红色标注的表示类
- Collection集合是单列集合的顶层接口,Map集合是双列集合的顶层接口
- Collection集合下存在两个子接口:List和Set; List接口的特点存储的元素可以重复,Set接口的特点存储的元素不可重复;
集合整体的学习思路: 从上往下进行学习。因为最顶层定义的是该体系中共性的功能,当我们把共性的功能学习完毕以后,在学习它下层集合时,我们只需要去学习其特有的功能即可。今天我
们重点介绍的是单列集合的使用。
2 Collection成员方法
成员方法:
boolean add(E e) // 添加元素
boolean remove(Object o); // 从集合中移除指定的元素
default boolean removeIf(Predicate<? super E> filter) // 根据指定的条件从集合中删除元素
void clear(); // 清空集合中的元素
boolean contains(Object o); // 判断集合中是否存在指定的元素
boolean isEmpty() // 判断集合是否为空
int size() // 集合的长度,也就是集合中元素的个数
代码示例:
public class MyCollectonDemo2 {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
// boolean add(E e) 添加元素
collection.add("aaa");
collection.add("bbb");
collection.add("ccc");
collection.add("dddd");
//System.out.println(collection);
//method1(collection);
//method2(collection);
//method3(collection);
//method4(collection);
//method5(collection);
//method6(collection);
}
private static void method6(Collection<String> collection) {
// int size() 集合的长度,也就是集合中元素的个数
int size = collection.size();
System.out.println(size);
}
private static void method5(Collection<String> collection) {
// boolean isEmpty() 判断集合是否为空
collection.clear();
boolean result = collection.isEmpty();
System.out.println(result);
}
private static void method4(Collection<String> collection) {
// boolean contains(Object o) 判断集合中是否存在指定的元素
boolean result = collection.contains("a");
System.out.println(result);
boolean result2 = collection.contains("aaa");
System.out.println(result2);
}
private static void method3(Collection<String> collection) {
// void clear() 清空集合
//就是将集合中所有的元素全部删除.
collection.clear();
System.out.println(collection);
}
private static void method2(Collection<String> collection) {
// boolean removeif(Object o) 根据条件进行删除
//removeif底层会遍历集合,得到集合中的每一个元素
//s依次表示集合中的每一个元素
//就会把这每一个元素都到lambda表达式中去判断一下
//如果返回的是true,则删除
//如果返回的是false,则保留不删除.
//boolean test(String t);
collection.removeIf(
(String s)->{
return s.length() == 3;
}
);
System.out.println(collection);
}
private static void method1(Collection<String> collection) {
// boolean remove(Object o) 从集合中移除指定的元素
//如果删除成功了,则返回true
//如果删除失败了,则返回false
boolean result1 = collection.remove("aaa");
boolean result2 = collection.remove("ddd");
System.out.println(result1);
System.out.println(result2);
System.out.println(collection);
}
}
3 遍历
3.1 迭代器
3.1.1 迭代器的使用
作用:遍历Collection集合的
使用迭代器遍历集合的思路:
1、调用集合对象的方法获取迭代器对象
Iterator<E> iterator(); // Iterator表示的就是迭代器
2、调用迭代器对象的相关方法从集合中获取元素
boolean hasNext(); // 判断集合中是否还存在元素
E next(); // 获取集合中的元素,E这种元素类型就是集合中所存储的元素的类型
代码实现:
public class MyCollectonDemo3 {
public static void main(String[] args) {
// 创建集合对象,并且添加元素
Collection<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
//1,获得迭代器的对象
//迭代器对象一旦被创建出来,默认指向集合的0索引处
Iterator<String> it = list.iterator();
// 遍历操作
while(it.hasNext()){
System.out.println(it.next());
}
}
}
3.1.2 迭代器的原理
在迭代器内部其实维护了一个指针(箭头),这个指针开始指向的位置就是集合中的第一个元素,每一次调用next方法的时候,都会取出当前位置的元素,并且指针向后移动一位。
3.1.3 删除集合元素
public class MyCollectonDemo5 {
public static void main(String[] args) {
Collection<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("d");
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
if("b".equals(s)){
//指向谁,那么此时就删除谁.
it.remove();
}
}
System.out.println(list);
}
}
3.2 增强for循环
作用:遍历Collection集合或者数组
格式:
for(数据类型 变量名 : 要遍历的数组或者集合名) { // 变量中记录的就是容器中的一个个的元素
// 对变量进行操作
}
示例:
public class MyCollectionDemo8 {
public static void main(String[] args) {
// 定义一个数组
int[] arr = {23 , 45 , 89 , 21} ;
// 普通for循环进行遍历
for(int x = 0 ; x < arr.length ; x++) {
System.out.println(arr[x]);
}
System.out.println("-------------------------------------");
// 使用增强for循环
for(int a : arr) {
System.out.println(a);
}
System.out.println("-------------------------------------");
// 使用增强for循环遍历Collection集合
Collection<String> col = new ArrayList<String>() ;
col.add("itcast") ;
col.add("itheima") ;
col.add("呵呵") ;
for(String a : col) {
System.out.println(a);
}
}
}
3.3 forEach方法
使用forEach方法可以对Collection集合进行遍历。
// 使用增强for循环遍历Collection集合
Collection<String> col = new ArrayList<String>() ;
col.add("itcast") ;
col.add("itheima") ;
col.add("呵呵") ;
// default void forEach(Consumer<? super T> action)
// col.forEach( s -> System.out.println(s) );
col.forEach( (String s) -> {
System.out.println(s);
});
3.4 练习题
需求:创建一个Collection集合存储学生对象,存储3个学生对象,使用程序实现在控制台遍历该集合
思路:
0、创建学生类(姓名、年龄)
1、创建Collection集合对象(多态的方式)
2、创建3个学生对象
3、把3个学生对象添加到集合中
4、遍历
- 迭代器
- 增强for
- forEach方法
代码实现:
public class CollectionDemo01 {
public static void main(String[] args) {
// 创建集合对象
Collection<Student> students = new ArrayList<Student>() ;
// 创建学生对象
Student s1 = new Student("itcast" , 16) ;
Student s2 = new Student("itheima" , 18) ;
Student s3 = new Student("柳岩" , 18) ;
// 把学生对象添加到集合中
students.add(s1) ;
students.add(s2) ;
students.add(s3) ;
// 遍历
// 1.1 使用迭代器
Iterator<Student> it = students.iterator();
while(it.hasNext()) {
Student student = it.next();
System.out.println(student.getName() + "---" + student.getAge());
}
System.out.println("----------------------------------------------");
// 1.2 使用增强for循环
for(Student s : students) {
System.out.println(s.getName() + "---" + s.getAge());
}
System.out.println("----------------------------------------------");
// 1.3 使用forEach方法
students.forEach( s -> System.out.println(s.getName() + "---" + s.getAge()));
}
}
4 List接口
4.1 List接口的特点
概述:List集合是Collection集合的一个子接口
特点:
1、元素有序(存取顺序一致)
2、元素可以重复
3、每一个元素都存在对应的索引,可以使用普通for循环进行遍历
4.2 特有方法
特有方法:
void add(int index,E element) // 在此集合中的指定位置插入指定的元素
E remove(int index) // 删除指定索引处的元素,返回被删除的元素
E set(int index,E element) // 修改指定索引处的元素,返回被修改的元素
E get(int index) // 返回指定索引处的元素
4.3 List集合的遍历
4.3.1 普通for循环
public class MyListDemo1 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("itcast") ;
list.add("柳岩") ;
list.add("周星驰") ;
for(int x = 0 ; x < list.size() ; x++) {
String s = list.get(x);
System.out.println(s);
}
}
}
4.3.2 迭代器
4.3.3 增强for
4.3.4 forEach方法
5 数据结构
概述:数据结构就是存储数据的方式
常见的数据结构:
1、栈
2、队列
3、数组
4、链表
5、哈希表
6、树
栈的特点:先进后出
队列的特点:先进先出
数组的特点:查询相对比较快,增删慢
链表的特点:查询比较慢,增删快
6 ArrayList扩容原理
ArrayList底层的数据结构是数组,当我们使用空参的构造方法创建一个ArrayList集合对象的时候,在底层会创建一个数组(elementData),数组的长度为0。当我们向其添加第一个元素的时
候,此时会对数组进行初始化,初始化的长度是10。当我们添加的元素大于10个的时候,此时就会进行扩容,新的数组的长度是源数组长度的1.5倍。
7 LinkedList
7.1 基本使用
集合的使用步骤总结:
1、创建集合对象
2、添加元素
3、遍历集合
示例代码:
public class MyLinkedListDemo3 {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("-------------------------");
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
System.out.println("--------------------------");
for (String s : list) {
System.out.println(s);
}
}
}
7.2 特有方法
特有方法:
public void addFirst(E e) // 将指定的元素添加到集合的头部
public void addLast(E e) // 将指定的元素添加到集合尾部
public E getFirst() // 获取集合中的第一个元素
public E getLast() // 获取集合中的最后一个元素
public E removeFirst() // 删除集合中的第一个元素,返回被删除的元素
public E removeLast() // 删除集合中的最后一个元素,返回被删除的元素
7.3 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;
}
}
获取元素的时候,会判断这个元素离头近,还是离尾近,如果是离头近,从前往后进行遍历获取元素。如果是离尾近,从后往前进行遍历,获取数据。
删除集合中的第一个元素,返回被删除的元素
public E removeLast() // 删除集合中的最后一个元素,返回被删除的元素
## 7.3 LinkedList原理
底层的数据结构就是**双向链表**
```java
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;
}
}
获取元素的时候,会判断这个元素离头近,还是离尾近,如果是离头近,从前往后进行遍历获取元素。如果是离尾近,从后往前进行遍历,获取数据。