【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;}@Overridepublic 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);}@Overridepublic 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.增强forfor (String s : list) {System.out.println(s);}//3.lambda表达式/*list.forEach(new Consumer<String>(){@Overridepublic 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 循环进行遍历。