一、Collection & List
1.1 Collection
概述:是单列集合的顶层接口,表示一组对象;这些对象也称为Collection的元素,JDK不提供此接口的实现类,必须通过其子接口如(Set,List)实现。
//创建Collection集合的对象 通过多态具体实现类ArrayList实现
//Collection<E> collection = new ArrayList<E>();
Collection<String> collection = new ArrayList<String>();
//Collection集合的常用方法:
//boolean add(E e) 添加元素
cllection.add("hello");
cllection.add("world!");
cllection.add("java");
//boolean remove(Object o) 从集合中删除指定元素
//cllection.remove("java");
//boolean contains(Object o) 判断集合中是否有指定元素
collection.contains("java");
//boolean isEmpty() 判断集合是否为空
collection.isEmpty();
//boolean clear(); 删除集合中所有的元素
//collection.clear();
//int size() 返回该集合长度 也就是集合中元素个数
collection.size();
Collection集合的遍历,通过Collection对象创建Iterator对象,利用iterator的方法实现集合的遍历。
//创建迭代器对象,迭代器是依赖于集合的
Iterator<String> it = collection.iterator();
//Iterator 常用方法:
//E next() 遍历下一个迭代器元素
//System.out.println(it.next());
//hello
//boolean hasNext() 判断此迭代器中是否还有元素
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
//hello
//world
//java
//void remove() 此方法无返回值,所以在使用时前一般加一个判断 注意此方法是删除集合中的元素 而不是迭代器中的元素
if(it.next.equals("java")){
iterator.remove()
}
集合通过迭代器对象遍历步骤:
①创建集合对象(多态)
②添加集合对象 .add
③通过集合对象创建迭代器对象遍历数组
④通过hsaNext() 判断集合中是否还有元素
⑤通过next() 遍历输出元素
1.2 List
概述:有序集合(也称为序列),用户可以精确的控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素。与Set不同,列表允许出现重复的元素。
List集合的特点:
①有序:存储和取出的元素顺序一致;
②可重复:存储的元素数据允许重复
//创建集合对象
List<String> list = new ArrayList<>();
//添加元素
list.add("java");
list.add("hello");
list.add("world");
list.add("world");
//void add(int index,E element) 在集合中指定索引位置添加元素
list.add(3,"big");
//E remove(int index) 删除集合中指定索引位置的元素,返回被删除元素
System.out.println(list.remove(2));
//E set(int index,E element) 更改集合中指定索引位置的元素值,返回被更改的元素返回被修改元素为修改前元素
System.out.println(list.set(0, "JAVA"));
//E get(int index) 返回集合中指定索引位置处的元素
System.out.println(list.get(2));
List集合的遍历:通过List对象创建ListIterator对象,利用Listiterator的方法实现集合的遍历。
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("java");
//创建ListIterator对象
ListIterator<String> listIterator = list.listIterator();
//正向遍历
while(listIterator.hasNext()){
String s = listIterator.next();
System.out.println(s);
}
//反向遍历
System.out.println("------------------");
while (listIterator.hasPrevious()){
String s = listIterator.previous();
System.out.println(s);
}
1.3 并发修改异常:ConcurrentModificationException(在Iterator迭代器中使用会出现)
在使用迭代器的next()时有同时使用了add()方法就会出现此异常,原因是因为在next()中会有一个预期改变次数和实际改变次数的判断,表达式为假就会抛出此异常。而再调用add()就会使实际修改次数改变从而使得next()里的表达式为假,从而抛出异常!
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("java");
//利用迭代器遍历集合 遇到java时添加javaee
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String s = iterator.next();
if (s.equals("java")){
list.add("javaee");
}
}
System.out.println(list);
//ConcurrentModificationException 并发修改异常
// 在使用迭代器的next()时的底层会有一个 expectedModCount(预期修改次数) = modCount(实际修改次数)判断,当判断
//当表达式为假时就会抛出 并发修改异常 ConcurrentModificationException
//在调用add方法后就会把实际修改次数++,这就使得预期修改次数和实际修改次数不符合
解决方法就是用for循环,使用list的get() ,再调用add(),因为get()中没有预期次数与实际次数的判断。
// 解决方式:使用for循环 不使用迭代器
for (int i = 0;i < list.size();i++){
String s = list.get(i);
if (s.equals("java")){
list.add("javaee");
}
}
System.out.println(list);
//此方法就不会报错 ,因为在源码中get()中没有 预期判断次数与实际判断次数的比较
1.4 ListIterator迭代器,与Iterator同样的操作使用不会出现并发修改异常:ConcurrentModificationException
while (listIterator.hasNext()){
String s = listIterator.next();
if (s.equals("java")){
listIterator.add("javaee");
}
}
System.out.println(list);
//此处虽然也使用了listIterator()的next()和add()方法但不会抛异常
//因为列表迭代器里的next()方法 expectedModCount = modCount; 会将实际操作次数再赋值给预期操作次数
//因此他们就同步了,表达式不会为假
1.5 for增强型
增强for循环:简化数组和Collection集合的遍历,实现terable接口的类允许其他对象成为增强型for语句的目标,其内部原理就是一个Iterator迭代器。
/*
格式:for(元素数据类型 变量名:数组或者Collection集合){
//此处使用变量即可,该变量就是元素
}
*/
int[] arr = {1,2,3,4,5};
//for增强 一个整型数组
for (int i : arr){
System.out.print(i+" ");
}
System.out.println("\n------------");
//for增强 一个字符串数组
String[] strArray = {"hello","world","java"};
for (String s : strArray){
System.out.print(s + " ");
}
System.out.println("\n------------");
//for增强 一个List集合
List<String> list = new ArrayList<>();
list.add("Pamela");
list.add("Jake");
list.add("Rose");
for (String s: list){
System.out.println(s);
}
/*
//其内部是一个Iterator迭代器
for (String s : list){
if (s.equals("Rose")){
list.add("pink");
}
}
System.out.println(list);
//会抛出并发修改异常 ConcurrentModificationException
*/
增强for循环练习:
需求:List集合存储学生对象用三种方式遍历
package com.itheima08;
/**
* @Date 2022/5/12 14:44
* @Author PAMELA
* @Description 学生属性类 用于测试List遍历
*/
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.itheima08;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @Date 2022/5/12 17:47
* @Author PAMELA
* @Description List集合存储学生对象用三种方式遍历
*/
public class ThreeTraverse {
public static void main(String[] args) {
Student student1 = new Student("Rose",20);
Student student2 = new Student("Pamela",18);
Student student3 = new Student("Jeane",23);
List<Student> list = new ArrayList<>();
list.add(student1);
list.add(student2);
list.add(student3);
//遍历方式一 Iterator迭代器
Iterator<Student> iterator = list.iterator();
while (iterator.hasNext()){
Student student = iterator.next();
System.out.println(student);
}
System.out.println("----------------------");
//遍历方式二 普通for循环
for (int i = 0;i < list.size();i++){
Student student = list.get(i);
System.out.println(student);
}
System.out.println("----------------------");
//遍历方式三 增强For循环
for (Student student : list){
System.out.println(student);
}
}
}
1.6 List集合子类特点
ArrayList:底层数据结构是数组,查询快,增删慢(一般大多数使用ArrayList)
LinkedList:底层数据结构是链表,查询慢,增删快
ArrayList和LinkedList练习:
package src.com.itheima09;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* @Date 2022/5/12 19:12
* @Author PAMELA
* @Description 使用ArrayList(查询快,增删慢)和LinkedList(查询慢,增删快)完成存储字符串并遍历
*/
public class ArrayList_LinkedListTraverse {
public static void main(String[] args) {
/**
* ArrayList完成存储字符串并遍历
*/
List<String> list = new ArrayList<>();
list.add("hello");
list.add("I");
list.add("am");
list.add("fine");
//遍历方式一:Iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
System.out.print(s + " ");
}
System.out.println("\n-----------------");
//遍历方式二:普通for循环
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.print(s + " ");
}
System.out.println("\n------------------");
//遍历方式三:增强for循环
for (String s : list) {
System.out.print(s + " ");
}
System.out.println("\n--------*********---------");
/**
* LikedList完成存储字符串并遍历
*/
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("hello");
linkedList.add("world");
linkedList.add("java");
//遍历方式一:iterator
Iterator<String> iterator1 = linkedList.iterator();
while (iterator1.hasNext()) {
String s = iterator1.next();
System.out.print(s + " ");
}
System.out.println("\n-----------------");
//遍历方式二:普通for循环
for (int i = 0; i < linkedList.size(); i++) {
String s = linkedList.get(i);
System.out.print(s + " ");
}
System.out.println("\n-----------------");
//遍历方式三:增强for循环
for (String s : linkedList){
System.out.print(s + " ");
}
}
}
三种遍历方式 遍历ArrayList集合
package src.com.itheima10;
/**
* @Date 2022/5/12 10:22
* @Author PAMELA
* @Description 学生属性类
*/
public class Student {
private String name;
private int num;
public Student(String name, int num) {
this.name = name;
this.num = num;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", num=" + num +
'}';
}
}
package src.com.itheima10;
import java.util.ArrayList;
import java.util.Iterator;
/**
* @Date 2022/5/12 19:59
* @Author PAMELA
* @Description ArrayList 集合存储学生对象用三种方式遍历
* 需求:创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合
*/
public class ArrayListThreeTraverse {
public static void main(String[] args) {
Student student1 = new Student("Jake",001);
Student student2 = new Student("Rose",002);
Student student3 = new Student("Lisa",003);
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(student1);
arrayList.add(student2);
arrayList.add(student3);
//遍历方式一:iterator
Iterator<Student> iterator = arrayList.iterator();
while (iterator.hasNext()){
Student student = iterator.next();
System.out.println(student);
}
System.out.println("----------------------------");
//遍历方式二:普通for循环
for (int i = 0;i < arrayList.size();i++){
Student student = arrayList.get(i);
System.out.println(student);
}
System.out.println("----------------------------");
//遍历方式三:增强for循环
for (Student student : arrayList){
System.out.println(student);
}
}
}
1.7 LinkedList集合的特有功能
package src.com.itheima11;
import java.util.LinkedList;
/**
* @Date 2022/5/12 20:18
* @Author PAMELA
* @Description 测试LinkedList的特有方法
*/
public class LinkedListTest {
public static void main(String[] args) {
//创建LinkedList集合 并添加元素
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("I");
linkedList.add("am");
linkedList.add("fine");
//public void addFirst(E e):在该列表开头插入指定的元素
linkedList.addFirst("Hi");
System.out.println(linkedList);
//public void addLast(E e):在列表结尾插入指定元素
linkedList.addLast("!");
System.out.println(linkedList);
//public E getFirst():获取列表开头第一位元素
System.out.println(linkedList.getFirst());
//public E getLast():获取列表结尾最后一个元素
System.out.println(linkedList.getLast());
//public E removeFirst():移除列表中的第一位元素
linkedList.removeFirst();
System.out.println(linkedList);
//public E removeLast():以后列表中的最后一位元素
linkedList.removeLast();
System.out.println(linkedList);
}
}
输出结果:
[Hi, I, am, fine]
[Hi, I, am, fine, !]
Hi
!
[I, am, fine, !]
[I, am, fine]