【JAVA入门】Day27 - 单列集合体系结构
文章目录
- 【JAVA入门】Day27 - 单列集合体系结构
- 1.1 Collection 集合的基本方法
- 1.2 Collection 集合的遍历方式
- 1.2.1 迭代器遍历
- 1.2.2 增强 for 遍历
- 1.2.3 利用 Lambda 表达式进行遍历
- 1.3 List 集合的基本方法
- 1.4 List 集合的遍历方式
Java 中的集合有一大堆,之前我们学习的 ArrayList 只是其中一种。
集合们有自己的体系结构,整体可以分为两类。
- 第一类是以 Collection 为首的单列集合。
- 第二类是以 Map 为首的双列集合。
所谓单列集合,其实就是每次往集合里添加数据的时候,只能添加一个数据;所谓双列集合,其实就是每次往集合里添加数据的时候,添加一对数据。
单列集合的所有共主是 Collection 类,之后会划分为 List 旁支和 Set 旁支。
List 系列集合的特点是:添加的元素是有序、可重复、有索引的。
所谓有序,就是“存”和“取”的顺序是一样的。
所谓可重复,表示集合中存储的元素是可以重复的。
所谓有索引,表示集合中的元素可以被索引访问。
Set 系列集合和 List 系列集合刚好相反,Set 集合添加的元素是无序、不重复、无索引的。
无序,表示“存”和“取”的顺序有可能是不一样的。
不重复,表示集合中存储中的元素不能出现一样的。
无索引,表示集合中存储的元素不能被索引访问。
1.1 Collection 集合的基本方法
Collection 是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的。
方法名称 | 说明 |
---|---|
public boolean add(E e) | 把给定的对象添加到当前集合中 |
public void clear() | 清空集合中所有的元素 |
public boolean remove(E e) | 把给定的对象在当前集合中删除 |
public boolean contains(Object obj) | 判断当前集合中是否包含给定的对象 |
public boolean isEmpty() | 判断当前集合是否为空 |
public int size() | 返回集合中元素的个数/集合的长度 |
package Colletcion;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo1 {
public static void main(String[] args) {
/* |方法名称| 说明 |
|--|--|
| public boolean add(E e) | 把给定的对象添加到当前集合中 |
| public void clear() | 清空集合中所有的元素 |
| public boolean remove(E e) | 把给定的对象在当前集合中删除 |
| public boolean contains(Object obj) | 判断当前集合中是否包含给定的对象 |
| public boolean isEmpty() | 判断当前集合是否为空 |
| public int size() | 返回集合中元素的个数/集合的长度 |
注意点:Collection是一个接口,我们不能直接创建他的对象。
所以,我们学习他时,只能创建他实现类的对象。
比如他的实现类有:ArrayList
*/
//为了学习Collection内部的方法
//我们利用多态,把子类对象赋值给Collection,这样可以直接调用Collection里的方法
Collection<String> coll = new ArrayList<String>();
//1.添加元素
//add方法有返回值,如果我们要往List系列集合中添加数据,那么方法永远返回true,因为List系列允许元素重复
//如果我们要给Set系列集合添加元素,如果要添加的元素在集合中不存在,方法返回true;如果要添加的元素已经存在,方法返回false,表示添加失败
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
System.out.println(coll);
//2.清空元素 coll.clear();
//System.out.println(coll);
//3.删除
//注意:因为Collection定义的方法是共性的方法,所以不能通过索引删除。只能通过元素的对象进行删除。
//删除也有返回值,删除成功返回true;删除失败返回false
//如果你给的参数这个元素在集合中不存在,就会删除失败
coll.remove("aaa");
System.out.println(coll);
//4.判断元素是否包含
//细节:contains方法底层是依赖equals方法进行判断是否存在的
//所以,如果集合中存储的是自定义对象,也想通过contains方法来判断是否包含
//那么,在Javabean中一定要重写equals方法
boolean result = coll.contains("aaa");
System.out.println(result); //false
//5.判断集合是否为空
boolean result2 = coll.isEmpty();
System.out.println(result2);
//6.返回集合元素个数
int num = coll.size();
System.out.println(num);
}
}
这里面要注意 contains 方法的使用,在判断是否含有自定义对象类型元素时,需要在 Student 类中重写 equals 方法。
package Colletcion;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo2 {
public static void main(String[] args) {
//1.创建集合对象
Collection<Student> coll = new ArrayList<>();
//2.创建三个学生对象
Student stu1 = new Student("zhangsan",31);
Student stu2 = new Student("wangwu",22);
Student stu3 = new Student("zhaoliu",18);
//3.把学生对象添加到集合中
coll.add(stu1);
coll.add(stu2);
coll.add(stu3);
//4.判断集合中某一个学生对象是否包含
//如果同姓名同年龄,那么就认为是同一个学生
Student stu4 = new Student("zhangsan" ,31);
//contains方法在底层是依赖equals方法判断对象是否一致的
//如果存的是自定义对象,没有重写equals方法,那么默认使用Object类中的equals方法进行判断
//Object中的equals方法仅仅依赖地址值进行判断,不满足需求,故要提前在Student类中重写其equals方法
System.out.println(coll.contains(stu4)); //true
}
}
package Colletcion;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
1.2 Collection 集合的遍历方式
Collection集合主要有三种遍历方式:迭代器遍历、增强for遍历、Lambda表达式遍历。
以上三种遍历方式是单列集合通用的遍历方式,下面我们依次来学习。
1.2.1 迭代器遍历
用迭代器进行遍历,不依赖索引,它是集合专用的遍历方式,在 Java 中其类名写作 Iterator。
使用 Collection 集合获取迭代器,默认指向当前集合的 0 索引处。
Iterator<E> iterator();
然后利用集合中的两个方法来获取和遍历集合中的元素。
常用方法 | 说明 |
---|---|
boolean hasNext() | 判断当前位置是否有元素,有元素返回true,没有元素返回false |
E next() | 获取当前位置的元素,并将迭代器对象移向下一个位置 |
package Colletcion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Iterators {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("三");
coll.add("连");
coll.add("外");
coll.add("加");
coll.add("转");
coll.add("发");
coll.add("了");
coll.add("吗");
coll.add("?");
coll.add("?");
Iterator<String> it = coll.iterator();
//hasNext()表示获取当前位置是否有元素,可作为循环的判断依据
while(it.hasNext()){
String str = it.next();
System.out.print(str);
}
}
}
使用迭代器遍历时,要注意以下几点:
- 如果迭代器已经指向空,再调用 next 方法会报错:NoSuchElementException。
- 迭代器遍历完毕后,指针不会复位。
- 循环中只能用一次 next 方法。
- 迭代器遍历时,不能用集合的方法进行增加或删除,否则可能会发生指针异常。
1.2.2 增强 for 遍历
增强 for 的底层其实就是迭代器,它是为了简化迭代器的代码书写而诞生的。它在JDK5之后出现,其内部原理是一个 Iterator 迭代器。
注意,所有的单列集合和数组才能用增强 for 进行遍历。
格式:
for (元素的数据类型 变量名:数组或集合){
}
用例:
for (String s : list) {
System.out.println(s);
}
细节:
- 修改增强 for 中的变量,不会改变集合中原本的数据。
for (String s : list) {
s = "q";
}
这是因为第三方变量在遍历过程中,仅仅用于记录集合中的元素内容,而不涉及到集合中的元素本身,因此不会改变集合中元素的值。
1.2.3 利用 Lambda 表达式进行遍历
得益于 JDK8 开始的新技术 Lambda 表达式,遍历集合有了第三种方法。
如下代码,实现 Consumer 接口重写 accept 方法。
package Colletcion;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class LambdaTest {
public static void main(String[] args) {
//1.创建集合并添加元素
Collection<String> coll = new ArrayList<>();
coll.add("zhangsan");
coll.add("lisi");
coll.add("wangwu");
//2.利用匿名内部类的形式
//forEach底层其实也会自己遍历集合,依次得到每一个元素
//s就是记录每一个元素的遍历,传递给accept方法
/*coll.forEach(new Consumer<String>(){
@Override
//s依次表示集合中的每一个数据
public void accept(String s) {
System.out.println(s);
}
});*/
//lambda表达式
//() -> {}
coll.forEach(s -> System.out.println(s));
}
}
1.3 List 集合的基本方法
List 集合是 Collection 下的一种旁支,它的特点是:有序、有索引、可重复。Collection 中的方法,List 都有继承,而 List 集合加入了索引相关的方法,我们只需要再学习索引相关操作即可。
方法名称 | 说明 |
---|---|
void add(int index, E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index, E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
package Colletcion;
import java.util.ArrayList;
import java.util.List;
public class ListTest1 {
public static void main(String[] args) {
//1.创建一个集合
//List也是一个接口,不能直接创建对象
//利用多态,创建一个其实现类对象赋给它,就可以用它来调用方法
List<String> list = new ArrayList<>();
//2.添加元素
list.add("aaa");
list.add("bbb");
list.add("ccc");
//3.打印集合
System.out.println(list);
//4.在指定的索引处添加元素
//把元素添加到这个索引处,则原来这里的元素会依次往后移
list.add(1,"QQQ");
System.out.println(list);
/* //5.删除指定索引的元素
//返回值是被删除的元素
String remove = list.remove(0);
System.out.println(remove);
System.out.println(list);
//remove方法存在重载,在重载时,会优先调用实参和形参一致的方法
List<Integer> tempList = new ArrayList<>();
tempList.add(1);
tempList.add(2);
tempList.add(3);
tempList.remove(1); //这里的1不是元素1,而是1索引
//如果想确切删除1这个元素,可以手动装箱
Integer i = Integer.valueOf(1); //获取1的包装类对象
tempList.remove(i); //此时删除的就是1这个元素本身*/
//6.set方法修改元素
String result = list.set(0, "QQQ");
System.out.println(result);
System.out.println(list);
//7.get方法通过索引获取元素
String s = list.get(0);
System.out.println(s);
}
}
1.4 List 集合的遍历方式
List 集合继承于 Collection 集合,刚才介绍的三种 Collection 集合的遍历方式在这里仍然适用。List 集合一共有五种遍历方式:
- 迭代器遍历
- 列表迭代器遍历
- 增强 for 遍历
- Lambda 表达式遍历
- 基本 for 循环遍历
package Colletcion;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Consumer;
public class ListTest2 {
public static void main(String[] args) {
//创建集合并添加元素
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//1.迭代器方式
Iterator<String> it = list.iterator();
while(it.hasNext()) {
String str = it.next();
System.out.println(str);
}
//2.增强for
for (String s : list) {
System.out.println(s);
}
//3.lambda表达式
/*list.forEach(new Consumer<String>(){
@Override
public void accept(String s){
System.out.println(s);
}
});*/
list.forEach(s -> System.out.println(s));
//4.简单for循环
for(int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//5.列表迭代器
//列表迭代器是一个接口,不能直接创建对象
//hasNext() next() hasPrevious() previous() add()
//获取一个列表迭代器的对象用listIterator()方法
ListIterator<String> itr = list.listIterator();
while(itr.hasNext()) {
String str = itr.next();
//list迭代器额外添加了一个方法:在遍历过程中,可以添加元素
//下面的代码在“bbb”元素后添加了一个“QQQ”元素,调用迭代器本身的add()方法
if("bbb".equals(str)){
itr.add("QQQ");
}
}
System.out.println(list);
}
}
这五种遍历方式可以说是有不同的用途:
- 在遍历过程中,如果要删除元素,请使用迭代器遍历。
- 在遍历过程中,如果要添加元素,请使用列表迭代器遍历。
- 如果仅仅想遍历,那么使用增强 for 或 Lambda 表达式即可。
- 如果在遍历时想对索引进行操作,可以使用普通 for 循环进行遍历。