Java基础教程-07-集合(上)
1. 内部类
1.1 内部类相关
1.1.1 概述
类里边还有一个类, 外边那个类叫做外部类, 里边那个类叫做内部类.
1.1.2 示例
下述代码只要能看懂就行了, 关于内部类, 实际开发中我们用的最多的就是匿名内部类
public class A {
public class B{
}
}
1.1.3 分类
• 成员内部类
public class A { //外部类
public class B{ //成员内部类
}
}
• 局部内部类
public class A { //外部类
//外部类的成员方法
public void show() {
//局部内部类
class B {
}
}
}
1.2 匿名内部类
1.2.1 概述
匿名内部类指的就是没有名字的局部内部类.
1.2.2 前提
必须有一个类(抽象类, 普通类均可), 或者接口.
1.2.3 格式
new 类名或者接口名() {
//重写类或者接口中所有的抽象方法
};
1.2.4 本质
匿名内部类就是一个继承了类或者实现了接口的匿名的子类对象.
简单理解:
匿名内部类的本质就是一个子类对象.
1.2.5 使用场景
- 当对对象方法(即: 成员方法)仅调用一次的时候.
- 匿名内部类可以作为方法的实参进行传递.
1.2.6 示例
需求
- 定义Animal抽象类, 该类中有一个抽象方法eat().
- 在测试类的main方法中, 通过匿名内部类的形式创建Animal抽象类的子类对象.
- 调用Animal类中的eat()方法
参考代码
动物类:
//抽象类, 动物类.
public abstract class Animal {
//抽象方法: 表示吃饭.
public abstract void eat();
}
测试类:
public class AnimalTest {
public static void main(String[] args) {
//需求: 调用Animal#eat()方法.
//方式一: 传统做法, 搞一个Animal类的子类, 例如: Cat, 然后通过多态实现.
Animal an = new Cat(); //子类名: Cat, 对象名叫: an
an.eat();
System.out.println("-----------------------");
//方式二: 通过匿名对象实现.
/*
匿名对象解释:
概述:
没有名字的对象, 就叫匿名对象.
特点:
用完以后就会变成垃圾对象, 由GC在不确定的时间回收.
*/
//new Cat(): 就是一个继承了Animal类的子类(Cat)的匿名对象.
new Cat().eat(); //子类名: Cat, 对象名叫: ??
System.out.println("-----------------------");
//方式三: 通过匿名内部类实现.
//匿名内部类的本质: 就是一个继承了Animal类的子类的匿名对象.
new Animal() { //子类名: ??, 对象名叫: ??
//重写类或者接口中所有的抽象方法.
@Override
public void eat() {
System.out.println("我是通过匿名内部类的形式创建的 Animal类的子类对象");
}
}.eat();
}
}
运行结果为:
猫吃鱼!
-----------------------
猫吃鱼!
-----------------------
我是通过匿名内部类的形式创建的 Animal类的子类对象
注意: 当接口或者抽象类中的抽象方法在3个(含)以下时, 就可以考虑使用匿名内部类的形式来创建对象了.
2. 集合
2.1 概述
集合是用来存储多个同类型数据的容器, 它的长度是可以变化的.
2.2 集合的体系图
记忆
- 集合的顶层都是接口, 其中Collection接口是单列集合的顶层接口, Map接口是双列集合的顶层接口.
- Collection接口(单列集合)有两大子体系:
– List体系的特点是: 有序, 可重复.
– Set体系的特点是: 无序, 唯一. - 一个小技巧: 以后但凡我们学习一个新的体系时, 都建议采用学顶层, 用底层的方式来学习.
解释: 因为顶层封装的是整个继承体系的共性内容, 而底层才是具体的实现, 体现.
3 Collection集合
3.1 概述
Collection集合是单例集合的顶层接口, 里边定义了所有单列集合都共有的内容.
3.2 创建Collection对象
因为Collection是接口, 所以不能直接通过new关键字来创建它的对象, 那它如何创建对象呢?
我们可以通过多态的方式, 创建其子类对象, 从而实现创建Collection接口对象. 代码如下:
Collection list = new ArrayList();
解释:
- 集合后边的<数据类型>是泛型的意思, 泛型是用来限定集合中存储元素的数据类型的.
- 例如:
– Collection说明集合中只能存储字符串.
– Collection说明集合中只能存储整数. - 泛型只能是引用数据类型, 且在实际开发中, 泛型一般只结合集合来一起使用.
3.3 案例一: Collection入门
3.3.1 需求
- 创建Collection集合对象, 用来存储字符串.
- 调用Collection接口的add()方法, 往上述集合中添加3个字符串, 内容如下:
“hello”, “world”, “java” - 通过输出语句, 直接打印集合对象, 并观察结果.
3.3.2 参考代码
public class Demo01 {
public static void main(String[] args) {
//1.创建Collection集合对象, 用来存储字符串.
//Collection<String> coll = new ArrayList<String>();
//JDK1.7以后, 可以简化成: 如下格式
Collection<String> coll = new ArrayList<>();
//2.调用Collection接口的add()方法, 往上述集合中添加3个字符串, 内容如下:"hello", "world", "java"
coll.add("hello");
coll.add("world");
coll.add("java");
//3.通过输出语句, 直接打印集合对象, 并观察结果.
System.out.println("coll: " + coll); //ArrayList类已经重写了Object#toString()方法.
}
}
运行结果为:
coll: [hello, world, java]
3.4 Collection集合的成员方法
常用方法如下:
• public boolean add(E e) 添加元素.
• public boolean remove(Object obj) 从集合中移除指定的元素.
• public void clear() 清空集合对象
• public boolean contains(Object obj) 判断集合中是否包含指定的元素
• public boolean isEmpty() 判断集合是否为空
• public int size() 获取集合的长度, 即集合中元素的个数
需求
- 通过多态的形式, 创建Collection集合对象.
- 调用Collection接口的add()方法, 往上述集合中添加3个字符串, 内容如下:
“hello”, “world”, “java” - 分别测试上述的6个成员方法.
参考代码
public class Demo02 {
public static void main(String[] args) {
//1.通过多态的形式, 创建Collection集合对象.
Collection<String> coll = new ArrayList<>();
//2.调用Collection接口的add()方法, 往上述集合中添加3个字符串, 内容如下: hello", "world", "java"
//测试 public boolean add(E e) 添加元素, ArrayList类的add()方法返回值是true, 因为: List体系的特点是: 有序, 可重复.
coll.add("hello");
coll.add("world");
coll.add("java");
//3.分别测试上述的6个成员方法.
//测试 public boolean remove(Object obj) 从集合中移除指定的元素.
/* System.out.println(coll.remove("world")); //元素存在就移除, 返回true
System.out.println(coll.remove("world123")); //元素不存在就返回false.*/
//测试 public void clear() 清空集合对象
//coll.clear();
//测试 public boolean contains(Object obj) 判断集合中是否包含指定的元素
/*System.out.println(coll.contains("hello"));
System.out.println(coll.contains("java"));
System.out.println(coll.contains("java123"));*/
//测试 public boolean isEmpty() 判断集合是否为空 集合的长度为0, 返回true, 否则返回false
//System.out.println(coll.isEmpty());
//测试 public int size() 获取集合的长度, 即集合中元素的个数
System.out.println(coll.size());
//打印集合对象:
System.out.println("coll: " + coll);
}
}
运行结果为:
3
coll: [hello, world, java]
3.5 案例二: 遍历集合
3.5.1 需求
- 通过多态的形式, 创建Collection集合对象.
- 调用Collection接口的add()方法, 往上述集合中添加3个字符串, 内容如下:
“hello”, “world”, “java” - 通过迭代器遍历集合, 获取到每一个元素, 并打印到控制台上.
3.5.2 提示
public Iterator<E> iterator() //根据集合对象, 获取其对应的迭代器对象.
解释:
- 因为Iterator是接口, 所以这里返回的其实是Iterator接口的子类对象.
- 迭代器是依赖于集合而存在的.
• Iterator迭代器中的方法
public boolean hasNext() //判断迭代器中是否还有下一个元素.
public E next() //获取迭代器中的下一个元素.
3.5.3 参考代码
public class Demo03 {
public static void main(String[] args) {
//1.通过多态的形式, 创建Collection集合对象.
Collection<String> coll = new ArrayList<>();
//2.调用Collection接口的add()方法, 往上述集合中添加3个字符串, 内容如下:"hello", "world", "java"
/*String s1 = "hello";
coll.add(s1);*/
coll.add("hello");
coll.add("world");
coll.add("java");
//3.通过迭代器遍历集合, 获取到每一个元素, 并打印到控制台上.
//3.1 根据集合对象获取其对应的迭代器对象.
//多态
//接口 Iterator接口的子类对象
Iterator<String> it = coll.iterator();
//3.2 判断迭代器中是否有下一个元素.
while (it.hasNext()) {
//3.3 有就获取, 然后输出.
String s = it.next();
System.out.println(s);
}
}
}
运行结果为:
hello
world
java
3.6 总结: 集合的使用步骤
集合的步骤可以分为四大步三小步, 具体如下:
- 创建集合对象.
- 创建元素对象.
- 把元素添加到集合中.
- 遍历集合.
1. 根据集合对象获取其对应的迭代器对象.
通过Collection#iterator()方法实现.
2. 判断迭代器中是否有下一个元素.
通过Iterator#hasNext()方法实现.
3. 如果有, 就获取该元素.
通过Iterator#next()方法实现.
3.7 案例三: 存储自定义对象并遍历
3.7.1 需求
- 定义一个学生类, 属性为姓名和年龄.
- 创建Collection集合, 用来存储学生对象.
- 往Collection集合中, 添加3个学生的信息.
- 通过迭代器, 遍历集合.
3.7.2 参考代码
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
//案例: 演示Collection集合存储自定义对象, 并遍历.
//考察: 集合的使用步骤(4大步3小步)
public class Demo04 {
public static void main(String[] args) {
//1. 创建集合对象.
Collection<Student> coll = new ArrayList<>();
//2. 创建元素对象.
Student s1 = new Student("刘亦菲", 33);
Student s2 = new Student("赵丽颖", 31);
Student s3 = new Student("高圆圆", 35);
//Student s4 = new Student("丹丹", 18);
//3. 把元素对象添加到集合对象中.
coll.add(s1);
coll.add(s2);
coll.add(s3);
//coll.add(s4);
//4. 遍历集合.
//4.1 根据集合对象获取其对应的迭代器对象. Collection#iterator();
Iterator<Student> it = coll.iterator();
//4.2 判断迭代器中是否有下一个元素. Iterator#hasNext();
while (it.hasNext()) {
//4.3 有就获取. Iterator#next();
Student stu = it.next();
System.out.println(stu);
//不能写成如下的形式, 因为next()方法调用一次, 就会获取一个值.
//下边这个代码就属于: 判断一次, 获取两个值.
//System.out.println(it.next().getName() + "..." + it.next().getAge());
}
}
}
运行结果为:
Student{name='刘亦菲', age=33}
Student{name='赵丽颖', age=31}
Student{name='高圆圆', age=35}
4. List集合
4.1 概述
有序集合(也称为序列), 该界面的用户可以精确控制列表中每个元素的插入位置。且用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。与Collection集合不同,列表通常允许重复的元素。
简单记忆:
List集合的元素特点是: 有序, 可重复, 元素有索引.
• 有序: 指的是元素的存储顺序和取出顺序是一致的.
• 可重复: 指的是List集合可以存储重复的元素.
• 元素有索引: 指的是List集合中每个元素都是由索引的, 且索引是从0开始的.
4.2 案例一: List入门
4.2.1 需求
- 创建List集合, 用来存储字符串.
- 往List集合中添加4个字符串值, 分别是: “hello”, “world”, “java”, “world”
- 通过迭代器, 遍历List集合, 获取每一个元素, 并打印到控制台上.
4.2.2 参考代码
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Demo01 {
public static void main(String[] args) {
//1.创建List集合, 用来存储字符串.
List<String> list = new ArrayList<>();
//2.往List集合中添加4个字符串值, 分别是: "hello", "world", "java", "world"
list.add("hello");
list.add("world");
list.add("java");
list.add("world");
//3.通过迭代器, 遍历List集合, 获取每一个元素, 并打印到控制台上.
//3.1 获取迭代器.
Iterator<String> it = list.iterator();
//3.2 判断有没有元素.
/*while (it.hasNext()) {
//3.3. 获取元素.
String s = it.next();
System.out.println(s);
}*/
//简化版
while (it.hasNext())
//3.3. 获取元素.
{
System.out.println(it.next());
}
}
}
运行结果为:
hello
world
java
world
4.3 List集合特有的成员方法
4.3.1 常用方法
• public void add(int index, E element)
解释: 在集合的指定位置(索引), 插入指定的元素, 索引越界会报IndexOutOfBoundsException异常.
• public E remove(int index)
解释: 删除指定索引处的元素, 并返回被删除的元素, 索引越界会报IndexOutOfBoundsException异常.
• public E set(int index, E element)
解释: 修改指定索引处的元素为指定的值, 并返回修改前的元素, 索引越界会报IndexOutOfBoundsException异常.
• public E get(int index)
解释: 根据索引, 获取其对应的元素, 索引越界会报IndexOutOfBoundsException异常.
4.3.2 需求
- 创建List集合, 用来存储字符串.
- 往List集合中添加3个字符串值, 分别是: “hello”, “world”, “java”.
- 演示上述的4个方法.
4.3.3 代码演示
import java.util.ArrayList;
import java.util.List;
public class Demo02 {
public static void main(String[] args) {
//1.创建List集合, 用来存储字符串.
List<String> list = new ArrayList<>();
//2.往List集合中添加3个字符串值, 分别是: "hello", "world", "java".
list.add("hello");
list.add("world");
list.add("java");
//打印集合.
System.out.println("list: " + list);
System.out.println("------------------------");
List<Integer> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
list2.add(4);
list2.add(5);
list2.remove(3); //如果集合的泛型是Integer类型, 传入值后, 是按照索引走的.
System.out.println(list2); //1235
}
}
运行结果为:
list: [hello, world, java]
------------------------
[1, 2, 3, 5]
4.4 案例二: 遍历List集合
4.4.1 需求
- 创建List集合, 用来存储字符串.
- 往List集合中添加3个字符串值, 分别是: “hello”, “world”, “java”.
- 通过for循环 + size() + get()的形式, 遍历List集合.
4.4.2 参考代码
import java.util.ArrayList;
import java.util.List;
//案例: 演示List集合(独有)的遍历方式.
//思路: 通过for循环 + size() + get()的形式, 遍历List集合.
public class Demo03 {
public static void main(String[] args) {
//1.创建List集合, 用来存储字符串.
List<String> list = new ArrayList<>();
//2.往List集合中添加3个字符串值, 分别是: "hello", "world", "java".
list.add("hello");
list.add("world");
list.add("java");
//3. 通过for循环 + size() + get()的形式, 遍历List集合.
//分解版
/*System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));*/
//for循环版本
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
//补充: for循环遍历List集合的快捷键: itli
}
}
运行结果为:
hello
world
java
4.5 案例三: 存储自定义对象并遍历
4.5.1 需求
- 定义一个学生类, 属性为姓名和年龄.
- 创建List集合, 用来存储学生对象.
- 往List集合中, 添加3个学生的信息.
- 分别通过两种遍历方式, 来遍历List集合.
4.5.2 参考代码
import com.luokk.demo01_collection.Student;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
//案例:演示List集合存储自定义类型的对象并遍历.
public class Demo04 {
public static void main(String[] args) {
//1.定义一个学生类, 属性为姓名和年龄.
//2.创建List集合, 用来存储学生对象.
List<Student> list= new ArrayList<>();
//3.往List集合中, 添加3个学生的信息.
Student s1 = new Student("刘亦菲", 33);
Student s2 = new Student("赵丽颖", 31);
Student s3 = new Student("高圆圆", 35);
list.add(s1);
list.add(s2);
list.add(s3);
//4.分别通过两种遍历方式, 来遍历List集合.
//方式一: 通过迭代器实现.
Iterator<Student> it = list.iterator();
while (it.hasNext()) {
/*Student stu = it.next();
System.out.println(stu);*/
System.out.println(it.next());
}
System.out.println("--------------------");
//方式二: 通过for() + size() + get()方法实现.
for (int i = 0; i < list.size(); i++) {
Student stu = list.get(i);
System.out.println(stu);
}
}
}
运行结果为:
Student{name='刘亦菲', age=33}
Student{name='赵丽颖', age=31}
Student{name='高圆圆', age=35}
--------------------
Student{name='刘亦菲', age=33}
Student{name='赵丽颖', age=31}
Student{name='高圆圆', age=35}
4.6 列表迭代器
4.6.1 概述
列表迭代器指的是ListIterator接口, 它是List集合特有的迭代器.
该迭代器继承了Iterator迭代器,所以, 我们可以直接使用.
4.6.2 成员方法解释
• List集合中的成员方法
public ListIterator<E> listIterator() //根据List集合对象, 获取其对应的列表迭代器对象.
• ListIterator迭代器中的成员方法
public boolean hasPrevious() //判断列表迭代器中, 是否有上一个元素.
public E previous() //获取列表迭代器中的上一个元素.
4.6.3 案例: 列表迭代器入门
需求
- 创建List集合, 用来存储字符串.
- 往List集合中添加3个字符串值, 分别是: “hello”, “world”, “java”.
- 通过列表迭代器对List集合分别进行正向遍历和逆向遍历.
参考代码
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Demo01 {
public static void main(String[] args) {
//1.创建List集合, 用来存储字符串.
List<String> list = new ArrayList<>();
//2.往List集合中添加3个字符串值, 分别是: "hello", "world", "java".
list.add("hello");
list.add("world");
list.add("java");
//3.通过列表迭代器对List集合分别进行正向遍历和逆向遍历.
//3.1 通过ListIterator进行正向遍历.
ListIterator<String> lit = list.listIterator();
while(lit.hasNext()) {
String s = lit.next();
System.out.println(s);
}
System.out.println("----------------------------");
while(lit.hasPrevious()) {
String s = lit.previous();
System.out.println(s);
}
System.out.println(2 << 3); //每往左移动一次, 相当于乘以 2
System.out.println((2 << 4) - 1 );
}
}
运行结果为:
hello
world
java
----------------------------
java
world
hello
16
31
记忆: 通过列表迭代器进行逆向遍历之前, 必须先进行一次正向遍历.
4.7 并发修改异常
4.7.1 需求
- 创建List集合, 用来存储字符串.
- 往List集合中添加3个字符串值, 分别是: “hello”, “world”, “java”.
- 判断集合中是否有"world"元素, 如果有, 就往集合中添加一个"JavaEE".
4.7.2 参考代码
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class Demo02 {
public static void main(String[] args) {
//1.创建List集合, 用来存储字符串.
List<String> list = new ArrayList<>();
//2.往List集合中添加3个字符串值, 分别是: "hello", "world", "java".
list.add("hello");
list.add("world");
list.add("java");
//3.判断集合中是否有"world"元素, 如果有, 就往集合中添加一个"JavaEE".
//方式一: 使用普通的迭代器实现, 会报并发修改异常.
/*Iterator<String> it = list.iterator();
while(it.hasNext()) {
String s = it.next();
//判断是否是"world", 如果是, 就添加"JavaEE"
if ("world".equals(s)) {
list.add("JavaEE"); //并发
}
}*/
//方式二: 使用列表迭代器实现.
/* ListIterator<String> lit = list.listIterator();
while(lit.hasNext()) {
String s = lit.next();
//判断是否是"world", 如果是, 就添加"JavaEE"
if ("world".equals(s)) {
//细节一: 必须使用列表迭代器中的添加元素的方法. ListIterator#add();
lit.add("JavaEE"); //并发
}
}*/
//方式三: 使用for + size()解决.
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
//判断是否是"world", 如果是, 就添加"JavaEE"
if ("world".equals(s)) {
list.add("JavaEE"); //并发
}
}
//4. 打印集合
System.out.println("list: " + list);
}
}
运行结果为:
list: [hello, world, java, JavaEE]
4.7.3 问题描述
当使用普通迭代器(Iterator)遍历集合的同时, 又往集合中添加元素, 就会报并发修改异常.
4.7.4 产生原因
迭代器依赖于集合而存在, 在判断成功后, 集合中添加了新的元素, 而迭代器并不知道, 所以就报错了.
其实这个问题说的是: 迭代器遍历集合中的元素时, 不要使用集合对象去修改集合中的元素.
4.7.5 解决方案
• 方案一: 通过列表迭代器解决
注意:
- 必须使用列表迭代器中的添加元素的方法. 即: ListIterator#add()
- 这种方式添加的元素, 是跟在刚才迭代的元素后边的.
• 方案二: 通过for循环 + size()解决
注意: 这种方式添加的元素, 是在集合的最后位置添加的.
5. 增强for
5.1 概述
增强for是JDK1.5的新特性, 它是用来简化数组和Collection集合的遍历的.
5.2 格式
for(元素的数据类型 变量名 : 数组或者Collection集合对象) {
//上述的 变量名 代表的就是, 数组或者Collection集合中的每一个元素.
}
5.3 好处
增强for是用来简化数组和Collection集合的遍历的.
5.4 注意事项
要通过增强for遍历的数组或者Collection集合, 不能为null.
即: 增强for的目标要判断是否为null.
5.5 示例一: 遍历数组
5.5.1 需求
- 定义int类型的数组, 存储元素1, 2, 3, 4, 5.
- 通过增强for, 遍历上述的数组.
5.5.2 参考代码
public class Demo01 {
public static void main(String[] args) {
//1.定义int类型的数组, 存储元素1, 2, 3, 4, 5.
int[] arr = {1, 2, 3, 4, 5};
//arr = null;
//2.通过增强for, 遍历上述的数组.
for(int a: arr) {
//a: 表示的就是数组中的每一个元素
System.out.println(a);
}
//快捷键: iter
for (int i : arr) {
System.out.println(i);
}
}
}
运行结果为:
1
2
3
4
5
1
2
3
4
5
5.7 案例三: 遍历集合
5.7.1 需求
- 定义学生类, 属性为姓名和年龄.
- 创建List集合, 用来存储学生对象.
- 往集合中添加3个学生的信息.
- 通过增强for遍历上述的List集合.
5.7.2 参考代码
import com.luokk.demo01_collection.Student;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
//案例: ArrayList集合存储学生对象并遍历.
public class Demo02 {
public static void main(String[] args) {
//1.定义学生类, 属性为姓名和年龄.
//2.创建ArrayList集合, 用来存储学生信息.
ArrayList<Student> list = new ArrayList<>();
//3.往集合中添加3个学生对象.
list.add(new Student("刘亦菲", 33));
list.add(new Student("赵丽颖", 31));
list.add(new Student("高圆圆", 35));
//4.通过三种方式, 遍历上述的集合.
//方式一: 迭代器
Iterator<Student> it = list.iterator();
while (it.hasNext()) {
Student s = it.next();
System.out.println(s);
}
System.out.println("----------------------");
//方式二: 普通for
for (int i = 0; i < list.size(); i++) {
Student s = list.get(i);
System.out.println(s);
}
System.out.println("-------------------------");
//方式三: 增强for, 掌握.
for (Student s : list) {
System.out.println(s);
}
System.out.println("-------------------------");
//方式四: 列表迭代器, 掌握.
ListIterator<Student> lit = list.listIterator();
while (lit.hasNext()) {
Student s = lit.next();
System.out.println(s);
}
System.out.println("-------------------------");
//方式五: 把集合转成数组, 然后遍历. Collection#toArray(); 了解.
Object[] objs = list.toArray();
for (Object obj : objs) {
System.out.println(obj);
}
}
}
运行结果为:
Student{name='刘亦菲', age=33}
Student{name='赵丽颖', age=31}
Student{name='高圆圆', age=35}
----------------------
Student{name='刘亦菲', age=33}
Student{name='赵丽颖', age=31}
Student{name='高圆圆', age=35}
-------------------------
Student{name='刘亦菲', age=33}
Student{name='赵丽颖', age=31}
Student{name='高圆圆', age=35}
-------------------------
Student{name='刘亦菲', age=33}
Student{name='赵丽颖', age=31}
Student{name='高圆圆', age=35}
-------------------------
Student{name='刘亦菲', age=33}
Student{name='赵丽颖', age=31}
Student{name='高圆圆', age=35}
6. 常见的数据结构
6.1 概述
数据结构是计算机存储, 组织数据的方式. 它是指相互之间存在一种或多种特定关系的数据元素的集合. 通常情况下, 精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关.
大白话理解:
数据结构指的就是数据的组织方式.
6.2 常用的数据结构
• 栈
• 队列
• 数组
• 链表
7. List集合的子类
7.1 常用子类
List集合是一个接口, 它的常用子类有两个, 分别是ArrayList, LinkedList.
• ArrayList集合的特点: 底层数据结构是数组, 查询和修改快, 增删慢.
• LinkedList集合的特点: 底层数据结构是链表, 查询和修改慢, 增删快.
注意: 它们的相同点是, 都是有序的, 而且可以存储重复元素.
7.2 ArrayList集合
7.2.1 案例一: 存储字符串并遍历
需求
- 定义ArrayList集合, 存储3个字符串信息, 分别是: “hello”, “world”, “java”.
- 通过三种方式, 遍历上述的集合.
提示: 迭代器, 普通for, 增强for.
参考代码
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
//案例: 演示LinkedList集合入门.
//概述: LinkedList集合解释: 底层数据结构是链表, 所以增删快, 查询修改慢.
public class Demo01 {
public static void main(String[] args) {
//1.创建LinkedList集合对象, 存储字符串数据: "hello", "world", "java"
LinkedList<String> list = new LinkedList<>();
list.add("hello");
list.add("world");
list.add("java");
//2.遍历LinkedList集合.
//方式一: 普通的迭代器.
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
System.out.println("--------------------------------");
//方式二: 普通for
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
System.out.println("--------------------------------");
//方式三: 增强for
for (String s : list) {
System.out.println(s);
}
System.out.println("--------------------------------");
//方式四: 列表迭代器
ListIterator<String> lit = list.listIterator();
while (lit.hasNext()) {
String s = lit.next();
System.out.println(s);
}
System.out.println("--------------------------------");
//方式五: 转数组遍历
Object[] objs = list.toArray();
for (Object obj : objs) {
System.out.println(obj);
}
}
}
运行结果为:
hello
world
java
--------------------------------
hello
world
java
--------------------------------
hello
world
java
--------------------------------
hello
world
java
--------------------------------
hello
world
java
7.3 LinkedList集合
7.3.1 案例一: LinkedList入门
需求
- 创建LinkedList集合对象, 存储字符串数据: “hello”, “world”, “java”
- 遍历LinkedList集合.
参考代码
import java.util.LinkedList;
public class Demo02 {
public static void main(String[] args) {
//1.创建LinkedList集合对象, 存储字符串数据: "hello", "world", "java"
LinkedList<String> list = new LinkedList<>();
list.add("hello");
list.add("world");
list.add("java");
//2.分别演示上述的6个方法.
//演示添加.
/*list.addFirst("黑马程序员");
//list.addLast("传智播客");
list.add("传智播客");*/
//演示删除元素
//System.out.println(list.removeFirst());
//System.out.println(list.removeLast());
//演示获取
System.out.println(list.getFirst());
System.out.println(list.getLast());
//3, 打印集合
System.out.println("list: " + list);
}
}
运行结果为:
hello
java
list: [hello, world, java]
7.3.2 LinkedList的特有方法
LinkedList集合主要是用来操作头和尾元素的, 所以它里边定义了大量这类的方法, 常用的方法如下:
• public void addFirst(E e) 往列表的开头插入指定的元素
• public void addLast(E e) 往列表的末尾插入指定的元素
• public E removeFirst() 删除列表中的第一个元素, 并返回被删除的元素
• public E removeLast() 删除列表中的最后一个元素, 并返回被删除的元素.
• public E getFirst() 返回列表的第一个元素
• public E getLast() 返回列表的最后一个元素