java集合List-ArrayList-LinkedList-Vector

集合简介

集合概述

集合引入原因:
编程的时候如果要存储多个数据,使用长度固定的数组存储格式,不一定可以满足需求。

xhj理解:也就是数组存储格式是长度固定的,
动态初始化int[] arr = new int[x] ;
静态初始化int[] arr = {x,x,x};

集合类的特点:
提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变;
Java中集合按照存储结构分为单列集合Collection和双列集合Map;

集合的体系结构:
集合体系结构
理解xhj:
学习接口的原因是:当学了Collection接口后,再学习List接口,只需要学习List接口特有的内容即可;

学习实现类的原因是:接口不能直接创建对象并调用方法,而接口的实现类可以直接创建对象并实现方法调用;

List集合子类的特点

ArrayList、LinkedList、Vector

概述:

  • List集合常用子类:ArrayList、LinkedList
  • ArrayList集合实现List接口,是List接口的可调整大小的数组实现,特点:查询快,增删慢;
  • LinkedList集合实现List接口,底层是双链表实现List接口,特点:查询慢、增删快;

案例:使用ArrayList和LinkedList实现字符串的存储和遍历

分析:
因为List有三种遍历方式:
1 使用迭代器 iterator
List<E> list = new ArrayList<E>(); 创建List集合对象
Iterator<E> it = list.iterator(); 获取迭代器对象
while(it.hasNext()){ 判断是否有可迭代的对象
	E e = it.next();  获取迭代器中的元素
	}

2 使用简单for循环
List<E> list = new ArrayList<E>(); 创建list集合对象
for(int i = 0 ; i < list.size() ; i++){ 遍历集合中元素
	E e = list.get(i); get方法获取集合元素
	}
	
3 增强for循环获取元素
List<E> list = new ArrayList<E>(); 创建list集合对象
for(String str : list){
	//for循环括号里是 集合中元素类型 变量名:集合对象
}

案例完整代码:

//29-ListDemo 
public class ListDemo {
    public static void main(String[] args) {
    // ArrayList集合
        ArrayList<String> array = new ArrayList<String>();

        array.add("hello");
        array.add("java");
        array.add("world");

        //遍历
        Iterator<String> it = array.iterator();
        while(it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("---------------");

        for(int i = 0;i<array.size();i++){
            String s = array.get(i);
            System.out.println(s);
        }
        System.out.println("---------------");
        
// LinkedList集合
        LinkedList<String> linkL = new LinkedList<String>();

        linkL.add("go do it");
        linkL.add("just do it");
        for (String s : linkL){
            System.out.println(s);
        }
    }
}

案例:ArrayList集合存储学生对象并遍历

需求:创建一个存储学生对象的集合,存储三个学生对象,使用程序实现在控制台遍历该集合

// 215-test1-ArrayListDemo 
public class ArrayListDemo {
    public static void main(String[] args) {
        ArrayList<Student> array = new ArrayList<Student>();

        Student s1 = new Student("汪苏泷",33);
        Student s2 = new Student("许嵩", 36);
        Student s3 = new Student("徐良", 34);

        array.add(s1);
        array.add(s2);
        array.add(s3);

        // 迭代器遍历
        Iterator<Student> it = array.iterator();
        while(it.hasNext()){
            Student s = it.next();
            System.out.println(s.getName() + ", " + s.getAge());
        }
        System.out.println("------------");

		// 简单for循环遍历
        for (int i = 0;i<array.size(); i++){
            Student s = array.get(i);
            System.out.println(s.getName() + ", " + s.getAge());
        }
        System.out.println("-------------");

		// 增强for循环遍历
        for(Student stu:array){
            System.out.println(stu.getName() + ", " + stu.getAge());
        }
    }
}

List集合

概述

  • interface List< E >表示它是一个接口,并且参数是泛型
  • 软件包是java.util 表示使用时需要导包
  • List是个接口,不能直接实例化,需要借助它的实现类进行实例化;
  • 有序集合(又称为序列),用户可以精确控制列表中每个元素的插入位置,也可以通过整数索引访问元素,并搜索列表中的元素
  • 与Set集合不同,列表通常允许重复的元素
  • List继承自Collection,则可以采用迭代器进行元素遍历
  • List集合是有序的,它是按照元素的添加顺序来存储对象。

特点
有序:存储和取出的元素顺序一致;
可重复:存储的元素可以重复。

案例:

//29-test3
public class ListDemo1 {
    public static void main(String[] args){

        List<String> list = new ArrayList<String>();

        list.add("hello");
        list.add("world");
        list.add("java");
        list.add("world");

        System.out.println(list);
        //[hello, world, java] 输出
        // 说明list列表中 元素的存储和取出顺序相同

        //使用迭代器遍历元素
        Iterator<String> it = list.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

List集合常用方法

方法名说明
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素

理解xhj:

1 List集合常用方法中,带有index索引的,都不可以越界;且常用方法都带有index索引;
2 List集合遍历集合的形式 目前阶段有两种:

方法一:
Collection<E> c = new ArrayList<E>(); // 集合对象
E e = c.iterator(); // 使用迭代器获取集合对象的元素
while(e.hasNext()){ // 用于判断是否可以迭代多个元素
	e.next(); // 获取对象的元素
}

方法二:
List<E> list = new ArrayList<E>()//获取List对象
//遍历对象
forint i= 0;i < list.size();i++{ //size()方法是Collection的
	list.get(i); //获取集合元素
	}

案例:List集合存储学生对象并遍历

// 29-test2
//List集合存储学生对象并遍历
public class ListDemo {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<Student>();

        Student s1 = new Student("汪苏泷",33);
        Student s2 = new Student("许嵩",33);
        Student s3 = new Student("郁可唯",33);

        list.add(s1);
        list.add(s2);
        list.add(s3);

        // 遍历元素
        //方式一:采用迭代器的形式
        Iterator<Student> it = list.iterator();
        while(it.hasNext()){
            Student s = it.next();
            System.out.println(s.getName() + ", " + s.getAge());
        }

        System.out.println("-------------------");
        //方式二:采用for循环形式
        for(int i = 0 ; i < list.size(); i++){
            Student s = list.get(i);
            System.out.println(s.getName() + ", " + s.getAge());
        }
    }
}

ArrayList

概述

ArrayList<E>
  • 说明:
    ①可调整大小的数组实现。
    ②< E>:是一种特殊的数据类型,泛型。
    xhj理解:也就是集合中存储元素的数据类型

  • 在出现E的地方使用引用数据类型替换。
    例如:ArrayList< String >; ArrayList< Student >

扩展

2022/5/31
ArrayList元素可以是数组

构造方法和添加方法

方法名说明
public ArrayList()创建一个空的集合对象
public ArrayList(int initialCapacity)构造具有指定初始容量的空列表
public ArrayList(Collection < ? extends E > c)构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序创建
public boolean add(E e)将指定的元素追加到指定集合的末尾,返回true或false表示操作成功/操作失败
public void add(int index,E element)在此集合中的指定位置插入指定元素

案例:

//117--ArrayListDemo1
//ArrayList构造方法和添加对象
public class ArrayListDemo1 {
    public static void main(String[] args){
        //创建ArrayList对象——public ArrayList()构造方法
//        ArrayList<String> array = new ArrayList<>(); //两种方式都可以
		  ArrayList<String> array = new ArrayList<String>();
        ** jdk7之后的新特性,new ArrayList<> 尖括号的内容会根据前面的ArrayList<String>进行推断的。
        

        ** ArrayList添加方法——public boolean add(E e)
//        System.out.println(array.add("hello"));//输出true 主要用于判断添加是否成功,一般不进行输出。
        array.add("hello");
        array.add("java");
        array.add("world");
        //结果输出:array:[hello, java, world] 会自动在每个元素之间添加逗号

        ** Arraylist添加方法——public void add(int index,E element)
//        array.add(1, "lxm");
        // array:[hello, lxm, java, world]
        
         **ArrayList对象末尾之后再添加元素,末尾索引是2 所以要在末尾添加则索引应该是3
//        array.add(3,"lxm");
        // array:[hello, java, world, lxm]
        
        **ArrayList对象末尾之后隔几个元素添加元素,末尾索引是2,添加位置是4
//        array.add(4,"lxm");
        **报错:IndexOutOfBoundsException
        **总结 也就是说 public void add(int index,E element)方法index的范围是0-集合长度
        System.out.println("array:" + array);
    }
}

xhj理解:
public void add(int index,E element)方法index的范围是0-集合长度;
例如集合长度是3,则index索引值就是0,1,2,3

ArrayList集合常用方法

方法名说明举例
public boolean remove(Object o)删除指定的元素,返回删除是否成功集合.remove(Element e)
public E remove(int index)删除指定索引处的元素,返回被删除的元素集合.remove(index)
public E set(int index,E element)修改指定索引处的元素,返回被修改的元素集合.set(index,Element)
public E get(int index)返回指定所引处的元素集合.get(index)
public int size()返回集合中的元素的个数集合.size()

案例:

// 117--ArrayListDemo2
//ArrayList常用方法
public class ArrayListDemo2 {
        public static void main(String[] args){
            //创建集合对象 ArrayList
            ArrayList<String> array = new ArrayList<String>();
            //使用public boolean add(String s)方法,返回
            array.add("hello");
            array.add("java");
            array.add("world");

            **public boolean remove(Object o)——删除指定元素
            System.out.println(array.remove("hello"));
            //输出:true   array:[java, world]
            System.out.println(array.remove("javaee"));
            //输出:false  array:[hello, java, world]
            删除的元素在ArrayList对象中没有,所以array.remove没有执行,返回值是false

            **public E remove(int index)根据索引删除对应的值,返回被删除的元素
            System.out.println(array.remove(1));
            //输出java  array:[hello, world]
            System.out.println(array.remove(3));
            报错:IndexOutOfBoundsException 因为元素一共有3个 索引值应该最大是2

            **public E set(int index,E element)——根据索引修改指定元素,并返回被修改的元素
            System.out.println(array.set(1, "javaee"));
            //输出:java  array:[hello, javaee, world]
            System.out.println(array.set(3, "javaee"));
            //报错:IndexOutOfBoundsException

            **public E get(int index)——返回指定索引处的元素
            System.out.println(array.get(0));
            System.out.println(array.get(1));
            System.out.println(array.get(2));
            //输出:hello,java,world,array:[hello, java, world]
//            System.out.println(array.get(3));//报错索引溢出,IndexOutOfBoundsException

            **public int size():返回集合中元素的个数
            System.out.println(array.size());//输出3

            System.out.println("array:" + array);
        }
}
案例:存储字符串并遍历

需求:创建一个存储字符串的集合,存储3个字符串元素,使用程序实现在控制台遍历该集合
遍历集合对象的通用格式:

for(int i = 0 ; i < 集合对象.size(); i ++){
		集合对象.get(i)//指定索引处的元素
}

案例:

// 117
//案例:存储字符串并遍历
public class ArrayListTest1 {
    public static void main(String[] args){
        //需求:创建一个存储字符串的集合,存储3个字符串元素,使用程序实现在控制台遍历该集合

        //创建一个集合,用于存储字符串
        ArrayList<String> array = new ArrayList<String>();
        //通过public boolean add(E element)添加字符串元素
        array.add("time");
        array.add("tries");
        array.add("all");
        array.add("things");

        //通过for循环遍历该集合
        //元素获取 通过public E get(int index)获取
        //集合长度 通过public int size()获取
        for(int i = 0; i<array.size(); i++){
           if (i == array.size() - 1){
               System.out.println(array.get(i));
           }else{
               System.out.print(array.get(i) + " ");
           }
        }
    }
}
案例:存储学生对象并遍历

需求:创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合。

// 117
//存储学生对象并遍历
public class ArrayListDemo3 {
    //需求:创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合。
    public static void main(String[] args){
        //定义学生类
        //在另一个文件中

        //创建集合对象
        ArrayList<Student> stu = new ArrayList<Student>();
        //创建学生对象
        Student st1 = new Student("汪苏泷",33);
        Student st2 = new Student("许嵩",36);
        Student st3 = new Student("徐良",35);

        //添加学生对象到集合中
        stu.add(st1);
        stu.add(st2);
        stu.add(st3);

        //遍历集合,采用通用遍历格式实现
        for (int i = 0 ; i < stu.size(); i ++){
            Student s = stu.get(i);
            System.out.println(s.getName() + ", " + s.getAge());
        }
    }
}

另一个文件的Studentpublic class Student {

    // 创建private 修饰的成员变量
    private String name;
    private int age;
    // 创建无参、有参数的构造方法
    public Student(){ }

    public Student(String name,int age){
        this.name = name;
        this.age = age;
        //这里的this指代对象,修改的是成员变量 private修饰的值
    }

    // 创建成员变量对应的get/set方法
    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;
    }
}
案例:存储学生对象并遍历升级版

需求:创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合。学生的姓名和年龄来自于键盘录入。

//117
//案例:存储学生对象并遍历升级版
public class ArrayListTest2 {
    public static void main(String[] args){
       // 需求:创建一个存储学生对象的集合,存储3个学生对象,使用程序实现在控制台遍历该集合。学生的姓名和年龄来自于键盘录入.

        //定义学生类,为了方便键盘录入,年龄和名字都定义为String类型
//另一个文件已创建
        //创建集合对象
        ArrayList<Student1> array = new ArrayList<Student1>();

        //多次添加输入信息给学生对象,并将学生对象添加到集合中,使用for循环
        /*for(int i = 0 ;i < 3 ; i++){
            //键盘录入学生对象所需要的变量
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入学生的姓名:");
            String stuName = sc.nextLine();
            System.out.println("请输入学生的年龄");
            String stuAge = sc.nextLine();
            //创建学生对象,把键盘录入的数据赋值给学生对象的成员变量
            Student1 stu = new Student1(stuName,stuAge);
            array.add(stu);
        }*/
        inputStudent(array);
        inputStudent(array);
        inputStudent(array);

        System.out.println("-----------");
        for(int i = 0; i<array.size();i++){
            Student1 st = array.get(i);
            System.out.println(st.getName() + ", " + st.getAge());
        }
    }
    //使用方法实现
    //两个明确:参数 ArrayList<Student1>  返回值  void
    // 出错很多次了 方法不加static会报错
    public static void inputStudent(ArrayList<Student1> array){
        //键盘录入学生对象所需要的变量
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生的姓名:");
        String stuName = sc.nextLine();
        System.out.println("请输入学生的年龄");
        String stuAge = sc.nextLine();
        //创建学生对象,把键盘录入的数据赋值给学生对象的成员变量
        Student1 stu = new Student1(stuName,stuAge);
        array.add(stu);
    }
}

//Student1类
public class Student1 {
    //成员变量
    private String name;
    private String age;

    //构造方法
    public Student1(){}
    public Student1(String name,String age){
        this.name = name;
        this.age = age;
    }

    //set、get方法
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setAge(String age){
        this.age = age;
    }
    public String getAge(){
        return age;
    }
}
案例:学生成绩管理系统

注意事项:

1 System.exit(status:0);
可以实现java虚拟机(JVM)的退出; 

2 类的构造方法的快捷键
alt + insert ,insert = 数字键盘 先按下num lock 再按下数字0
或者:
小键盘旁边的Ins也是insert的意思。

3 关于\t的使用
System.out.println("\t") 这样可以实现tab键的位置

4 关于return
为了让程序不再往下执行,给出return5 String.equals(String)
字符串的值比较

6 学号删除中学号不存在问题判断
通过
int index = -1//用于标识学号是否存在与集合中
for(int i = 0;i<array.size();i++){
	StudentM s = array.get(i); 
	if(s.getSid().equals(sid)){ // s.getSid 遍历每个集合元素的sid属性。sid是要删除的学生的学号
		index = i;//存在于集合中,就修改index为对应的索引值
		break;//跳出循环,不执行后续的比较
	}
}

7 添加学生学号重复问题
通过方法判断:定义一个标识符flag标识学号是否重复》通过for循环遍历集合中元素,集合.get(index)获取集合元素》元素.getXxx()获取成员变量 》
学生学号 与 集合中对象的学号 进行比较,初始flag=-1,如果相同设置为flag设置为索引值。
public static int judgeSid(String sid,ArrayList<String> array){
	int flag = -1;
	for(int i = 0; i < array.size();i++){
		if(array.get(i).getSid().equals(sid)){
			// 学号重复,
			flag = i;
			}
	}
	return flag;
}

思路:

0 定义ArrayList集合存储学生对象 界面内容1添加2删除3修改4查看5退出  以及后续操作都存放在while死循环中。
while(true){
	0 界面
	0 获取要执行的功能编号 Scanner nextInt
	采用switch语句将选择情况包起来,
	1 添加学生 需要判重对于Sid
		先输入学号,进行判重,如果flag=-1则没有重复,继续执行后续nextLine获取学生信息,创建对象,添加到集合(array.add(学生对象))
		flag != -1 有重复,break2 删除学生 需要对Sid判断是否存在
		先输入学号,进行判断是否存在,如果flag=-1则不存在,不执行删除
		flag != -1 存在,执行array.remove(flag);
	3 修改学生 需要对Sid判断是否存在
		先输入学号,进行判断是否存在,如果flag=-1则不存在,不执行修改
		flag != -1 存在,执行对应的 对象.setxxx()属性方法。
	4 查看所有学生信息
		for循环遍历,条件控制语句是 array.size(),
		循环体是对象.getxxx()方法获得对象属性。
		
0Sid判重方法
	public static int jugeSid(String sid,ArrayList<Student> array){
		定义flag返回值,初始值是-1
		for循环遍历集合,对每个元素的sid属性和参数sid进行比较,相同则将flag改为对一个的索引值,不同则不改。
			循环控制条件 array.size()
			if(array.get(i).getSid().equals(sid)return flag

代码:

// 117
import java.util.ArrayList;
import java.util.Scanner;

//学生管理系统
public class StudentManager {
        public static void main(String[] args) {
            // 定义集合变量,用于存储学生
            ArrayList<StudentM> array = new ArrayList<StudentM>();
            //0主界面程序
            //0-4 选择完成,使用循环再次回到主界面,注意选择5之后,程序要退出而不是再次回到主界面。
            while (true) {
                //0-1 通过sout输出语句搭建主界面提示信息
                System.out.println("--------欢迎来到学生管理系统--------");
                System.out.println("1 添加学生");
                System.out.println("2 删除学生");
                System.out.println("3 修改学生");
                System.out.println("4 查看所有学生");
                System.out.println("5 退出");
                System.out.println("请输入你的选择:");
                //0-2 用Scanner获取键盘录入信息
                Scanner sc = new Scanner(System.in);
                String select = sc.nextLine();
                //0-3 使用switch分支实现对输入信息的判断,并执行对应操作
                switch (select) {
                    case "1":
//                        System.out.println("添加学生");
                        addStudent(array);
                        break;
                    case "2":
//                        System.out.println("删除学生");
                        delectStudent(array);
                        break;
                    case "3":
//                        System.out.println("修改学生");
                        updataStudent(array);
                        break;
                    case "4":
//                        System.out.println("查看所有学生");
                        viewStudent(array);
                        break;
                    case "5":
                        System.out.println("谢谢使用");
                        //break;//单纯的break不能实现跳出while死循环,只可以跳出switch分支。
                        System.exit(0);//使用此语句可以实现JVM退出,java虚拟机都退出了,程序一定退出了。
                    default:
                        System.out.println("输入内容有误");
                }

            }
        }

    //1 添加学生信息
    //返回值 void 参数ArrayList<StudentM> array
    public static void addStudent(ArrayList<StudentM> array){
            //思路一:没有考虑学号重复的问题。

           /* //Scanner获取输入内容
        Scanner sc = new Scanner(System.in);
            //1-0 给出添加信息
        System.out.println("请输入学生姓名:");
        String name = sc.nextLine();
        System.out.println("请输入学生学号:");
        String sid = sc.nextLine();
        System.out.println("请输入学生年龄");
        String age = sc.nextLine();
        System.out.println("请输入学生居住地:");
        String address = sc.nextLine();
        //1-1 创建学生对象,并将键盘录入的信息赋值给学生对象的成员变量
        StudentM s = new StudentM();
        s.setName(name);
        s.setSid(sid);
        s.setAge(age);
        s.setAddress(address);
        // 1-2 将学生对象添加到集合中
        array.add(s);
        // 1-3 给出添加学生信息成功提示
        System.out.println("信息添加成功!");*/

           //思路二:考虑学号重复问题。
        //创建方法用于判断输入学号是否处于集合中 相同返回true,不同返回false
        Scanner sc = new Scanner(System.in);
        // 将sid定义在while循环之外,是为了后续学生对象调用set方法实现
        String sid;
        //为了保证输入学号错误之后还重新显示输入学生学号提示信息。
        while(true) {
            System.out.println("请输入学生学号:");
            sid = sc.nextLine();
            boolean flag = judgeSid(sid, array);
            if (flag) {
                System.out.println("输入学生的学号已被使用,请重新输入");
            } else {
                break;
            }
        }
        System.out.println("请输入学生姓名:");
        String name = sc.nextLine();
        System.out.println("请输入学生年龄");
        String age = sc.nextLine();
        System.out.println("请输入学生居住地:");
        String address = sc.nextLine();
        //1-1 创建学生对象,并将键盘录入的信息赋值给学生对象的成员变量
        StudentM s = new StudentM();
        s.setName(name);
        s.setSid(sid);
        s.setAge(age);
        s.setAddress(address);
        // 1-2 将学生对象添加到集合中
        array.add(s);
        // 1-3 给出添加学生信息成功提示
        System.out.println("信息添加成功!");

    }

    //2 删除学生
    public static void delectStudent(ArrayList<StudentM> array){

            // 此情况没有考虑 输入删除学号不存在的情况:
/*            //2-0 输入要删除的学生的学号
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入要删除的学生的学号");
            String sid = sc.nextLine();
            //2-1 利用循环遍历集合中元素找到对应的索引值,
            for (int i = 0 ; i < array.size(); i++){
                StudentM stu = array.get(i);
                if(stu.getSid().equals(sid)){
                    //2-2 通过索引值使用remove方法删除学生对象
                    array.remove(i);
                    return;
                }
            }
            //2-3 返回删除成功信息
            System.out.println("删除成功");*/
            // 考虑删除学号不存在的情况,需要提前判断学号是否存在
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要删除学生的学号:");
        String sid = sc.nextLine();

        int index = -1;
        for (int i = 0 ; i < array.size(); i++){
            StudentM s = array.get(i);
            if(s.getSid().equals(sid)){
                index = i;
                break;
            }
        }
        if(index == -1){
            System.out.println("输入的学号有误,请重新输入");
        }else{
            array.remove(index);
            System.out.println("删除成功!");
        }
    }
    //3 修改学生
    public static void updataStudent(ArrayList<StudentM> array){
            //3-0 输入要修改的学生的学号
            Scanner sc = new Scanner(System.in);
            String sid;
            while(true) {
                System.out.println("请输入要修改的学生的学号:");
                sid = sc.nextLine();

//避免修改学生信息,学生信息不存在的情况
                boolean flag = judgeSid(sid, array);
                if (!flag) {
                    System.out.println("输入的要修改的学生的学号不存在,请重新输入");
                } else {
                    break;
                }
            }
            //3-1 输入要修改的学生的 其他信息
            System.out.println("请输入新的学生的姓名:");
            String name = sc.nextLine();
            System.out.println("请输入新的学生的年龄:");
            String age = sc.nextLine();
            System.out.println("请输入的新的学生的居住地");
            String address = sc.nextLine();

            // 思路一:通过方法学号找到它在集合中对应的索引 通过集合.get获取StudentM对象 然后通过对象.set方法重新赋值
//            //3-2 遍历集合找到对应的索引值
//            for(int i = 0; i<array.size();i++){
//                //3-3 修改对应值
//                StudentM s = array.get(i);
//                if (s.getSid().equals(sid)) {
//                    s.setName(name);
//                    s.setAge(age);
//                    s.setAddress(address);
//                }
//            }
//            //3-4 修改完成通知
//            System.out.println("修改已完成");

        //思路二:创建学生对象,通过键盘录入的信息
        // 使用循环遍历,通过sid找到集合中对应对象的索引值,通过集合.set(int index,E element)方法
        StudentM stu = new StudentM();
        stu.setName(name);
        stu.setAge(age);
        stu.setSid(sid);
        stu.setAddress(address);

        for(int i = 0; i< array.size() ; i++){
            StudentM s = array.get(i);
            if(s.getSid().equals(sid)){
                array.set(i, stu);
                //成功之后就不再往后执行了。
                break;
            }
        }
        //输出修改成功提示
        System.out.println("信息修改成功!");

    }


    //4 查看所有学生
    public static void viewStudent(ArrayList<StudentM> array){
            //判断集合中是否有内容 没有内容输出提示信息
        //可以不适用if else语句实现。在if语句体中写return即可。
/*        if(array.size() == 0){
            System.out.println("没有学生信息,请添加!");
        }else{
            //显示表头信息
            // \t 其实就是tab键的位置
            System.out.println("学号\t姓名\t\t年龄\t\t居住地");

            for(int i = 0 ;i <array.size(); i++){
                StudentM stuM = array.get(i); //返回的是StudentM对象
                System.out.println( stuM.getSid() + "\t\t" + stuM.getName() + "\t" + stuM.getAge() + "岁\t\t" + stuM.getAddress());
            }
        }*/
        if(array.size() == 0){
            System.out.println("没有学生信息,请添加!");
            //为了不让程序往下执行,给出return;
            return;
        }
            //显示表头信息
            // \t 其实就是tab键的位置
            System.out.println("学号\t姓名\t\t年龄\t\t居住地");
            for(int i = 0 ;i <array.size(); i++){
                StudentM stuM = array.get(i); //返回的是StudentM对象
                System.out.println( stuM.getSid() + "\t\t" + stuM.getName() + "\t" + stuM.getAge() + "岁\t\t" + stuM.getAddress());
            }
    }

    //1 用于判断学号重复的方法
    public static boolean judgeSid(String sid , ArrayList<StudentM> array){
          boolean flag = false;
          for(int i = 0; i < array.size(); i++){
              StudentM s = array.get(i);
              if(s.getSid().equals(sid)){
                  flag = true;
                  break;
              }
          }
          return flag;
    }
}

LinkedList

概述

  • public class LinkedList< E > extends AbstractSequentialList< E > implements List< E > , Deque< E > , Cloneable,Serializable

  • 继承自Deque
    LinkedList类是双向链表,列表中的每个节点都包含对前一个和对后一个元素的引用。
    LinkedList可以被当作堆栈、队列或者双端队列进行操作。
    LinkedList本质是双向链表,包含两个重要成员:header 和 size 。

    • header是双向链表的表头,它是双向链表节点所对应的类Entry的实例。Entry中包含成员变量:previous、next、element。其中previous是该节点的上一个,next是该节点的下一个,element是该节点所包含的值。
    • size是双向链表中节点的个数。
  • LinkedList的添加add操作,默认是队尾添加元素。

  • 继承自Serializable
    LinkedList实现了Serializable接口,所以可以被序列化,能通过序列化去传输。

  • LinkedList是非同步的。

构造函数

函数说明
LinkedList()默认构造函数
LinkedList(Collection<? extends E > collection)创建一个LinkedList,包含指定集合collection的全部元素

LinkedList集合的特有功能

方法名说明
public void addFirst(E e)在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素
public E pollLast()检索并删除此列表的最后一个元素,如果列表为空,返回null

案例:

//215-LinkedListDemo
public class LinkedListDemo {
    public static void main(String[] args){
        LinkedList<String> list = new LinkedList<String>();

        list.add("hello");
        list.add("java");
        list.add("world");

        System.out.println(list);
		list.addFirst("javaee");
        //在集合首位添加元素
        // 初始:[hello, java, world] 添加后:[javaee, hello, java, world]
		list.addLast("javase");
        //在集合尾部添加元素
        // 初始:[hello, java, world] 添加后:[hello, java, world, javase]
		System.out.println(list.getFirst());
        // 返回集合首位元素 hello
        // 初始:[hello, java, world]
		System.out.println(list.getLast());
        // 返回集合尾部元素 world
        // 初始:[hello, java, world]

		System.out.println(list.removeFirst());
        //删除集合首位元素 并返回 hello
        // 初始:[hello, java, world] 删除后: [java, world]
        System.out.println(list.removeLast());
        // 删除集合尾部元素并返回 world
        // 初始:[hello, java, world] 删除后:[hello, java]
        System.out.println(list);
    }
}

LinkedList一般方法

方法名说明
E remove()检索并删除此列表的第一个元素
E remove(int index)删除该列表中指定位置的元素
index位置的元素
boolean remove(object o)从列表中删除指定元素第一个出现的

Vector类

概述

  • Vector和ArrayList,底层采用的都是动态数组。
  • Vector是有序的,可以存储重复值和null值。
  • Vector是同步访问的,是有条件的线程安全;ArrayList,不是线程安全的;
  • 初始容量是10,没有设置扩容增量的情况下以自身的2倍容量扩容,可以设置容量增量,初始容量和扩容量可以通过构造函数public Vector(int initialCapacity, int capacityIncrement)进行初始化。
  • Vector适用情景:用在事先不知道数组的大小、或者需要一个可以改变大小的数组的情况。

构造方法

方法说明
Vector()创建一个默认大小是10的数组
Vector(int size)创建指定大小的数组
Vector(int size,int incr)创建指定大小的数组,并且增量用incr指定。增量表示向量每次增加的元素数目
Vector(Collection c)创建一个包含集合c元素的数组

列表迭代器ListIterator

概述

  • Listiterator列表迭代器,通过List集合的listiterator()方法得到 列表迭代器ListIterator< E > ,它是一个List集合特有的迭代器
  • ListIterator< E > 列表迭代器 软件包是 java.util,使用需要导包
  • public interface ListIterator< E > extends Iterator 则说明ListIterator可以直接使用Iterator中的next和hasnext方法
  • 迭代器没有当前所有元素一说,它只是一个游标(cursor)的概念,这个游标总是在元素之间。
  • 列表迭代器的特点:
    ①允许沿任一方向遍历列表
    在迭代期间可以修改列表中的元素
    ③获取列表中迭代器的当前位置

常用方法

方法名说明
e next()返回游标后的元素,
同时将游标后移一位
e previous()返回游标前面的元素,
同时将游标前移一位
Boolean hasNext()判断游标后面是否有元素
Boolean hasPrevious()判断游标前面是否有元素
int nextIndex()返回游标后面元素的索引值,初始值是0;
遍历N个元素结束时是N
int previousIndex()返回游标前面元素的索引值,初始值是-1,
同时报java.util.NoSuchElementException错
void add(e)在游标前插入一个元素
void set(e)更新迭代器最后一次操作的元素为E,更新最后一次调用next()或previous()返回的元素
当没有迭代,即没有执行next()或previous()时,直接使用set时会报 java.lang.illegalStateException错
void remove()删除迭代器最后一次操作的元素
当没有迭代,即没有执行next()或previous()时,直接使用remove时会报 java.lang.illegalStateException错

总结

最开始的list = 游标 you are my pretty sunshine
ListIterator<String> iter = list.listIterator();
代码list情况输出结果
iter.nextyou 游标 my pretty sunshineyou
iter.next
iter.previous
you 游标 are my pretty sunshine
游标 you are my pretty sunshine
you
you
iter.next
iter.nextIndex
iter.PreviousIndex
you 游标 are my pretty sunshineyou
1
0
iter.next
iter.add(e)
you 游标 are my pretty sunshine
you e 游标 are my pretty sunshine
you
void
iter.next
iter.set(e)
you 游标 are my pretty sunshine
e 游标 are my pretty sunshine
you
void
iter.next
iter.remove
you 游标 are my pretty sunshine
游标 are my pretty sunshine
you
void

案例

// 29-test1-ListIteratorDemo
public class ListIteratorDemo {

    public static void main(String[] args){
        List<String> list = new LinkedList<String>();
        list.add("you");
        list.add("are");
        list.add("my");
        list.add("pretty");
        list.add("sunshine");
        ListIterator<String> iter = list.listIterator();
        // 使用增强for循环遍历集合
        System.out.println("list集合");
        for(String str:list){
            System.out.print(str + " ");
        }
        System.out.println();
        System.out.println("---------------");

//        method7(iter);
//        method8(iter,list);
        method9(list);



    }
    // 测试iter.next
    public static void method(ListIterator<String> iter){
        System.out.println(iter.next());
        // 第一次执行next 输出 you
//        System.out.println(iter.next());
        // 第二次执行next 输出are

    }
    // 测试游标在列表最开始的位置执行previous方法
    public static void method2(ListIterator<String> iter){
        System.out.println(iter.previous());
        // 直接执行listIterator.previous 报错NoSuchElementException,因为初始值是-1
    }
    // 测试iter.next 和 iter.previous
    public static void method3(ListIterator<String> iter){
        System.out.println(iter.next());
        System.out.println(iter.previous());
        // 两者输出都是you,
        // 执行next操作之前,游标的位置是{游标 you are my pretty sunshine},执行next操作,输出you,并将游标先后移动,游标位置{you 游标 are my pretty sunshine}
        // 执行previous操作之前,游标位置{you 游标 are my pretty sunshine},所以游标前的数据是 you,并将游标前移,游标位置{游标 you are my pretty sunshine}
        System.out.println(iter.next());
//        // 输出结果还是you,游标位置{游标 you...},取游标后边的元素。
    }
    // 在最开始就执行nextIndex()
    public static void method4(ListIterator<String> iter){
        System.out.println(iter.nextIndex());
        // 输出结果是0
        // 执行nextIndex 之前没有执行next
    }
    // 册数nextIndex 和 previousIndex
    public static void method5(ListIterator<String> iter){
        iter.next();
        System.out.println(iter.nextIndex());
        // 输出结果是 1
        System.out.println(iter.previousIndex());
        // 输出结果是 0
    }
    // 测试set方法
    public static void method6(ListIterator<String> iter){
        iter.next();
        iter.set("xhj");
        // 修改了you的位置,此时集合元素是: xhj 游标 are
        System.out.println(iter.previous());
        // 输出的是 xhj
    }
    // 测试add方法
    public static void method7(ListIterator<String> iter){
            // 最开始 游标 you are
          iter.next();
          // 执行后 you 游标 are
          iter.add("xhj");
          // 在游标前插入元素 you xhj 游标 are
         System.out.println(iter.previous());
         // 输出xhj
    }

    // 测试remove方法
    public static void method8(ListIterator<String> iter,List<String> list){
        // 最开始 游标 you are
        iter.next();
        // 执行后 you 游标 are
        iter.remove();
        // 删除最近next.previous操作的元素
        System.out.println(list);
    }

获取ListIterator的方式

获取方式说明
list对象.listIterator()得到ListIterator对象
list对象.listIterator(int location)获得ListIterator对象且指定游标位置
location必须在[ 0,list对象.size() )
表示游标list索引location前

案例:针对location索引问题

// 29-test1-ListIteratorDemo
	List<String> list = new LinkedList<String>();

    list.add("you");
    list.add("are");
    list.add("my");
    list.add("pretty");
    list.add("sunshine");
 	** 测试 List listIterator(int location) 查看location是否有界限
	ListIterator<String> stringListIterator = list.listIterator(20);
	System.out.println(stringListIterator.next());
        //当索引超出list表长度的时候会报错。size是5,location是20
        // IndexOutOfBoundsException
        
	ListIterator<String> stringListIterator = list.listIterator(0);
	System.out.println(stringListIterator.next());
        // 索引是0,表示游标是在索引0的前面,则ListIterator.next会输出List的第一个元素
        
    ListIterator<String> stringListIterator = list.listIterator(4);
    System.out.println(stringListIterator.next());
        // 索引是4,表示游标是在索引4的前面,则ListIterator.next会输出List的第5个元素

案例:使用iterator迭代器使用add方法会报错,但是ListIterator迭代器使用add不会报错

// 29
public class ListIteratorDemo {
    public static void main(String[] args) {
         
        List<String> list = new ArrayList<String>();
        
        list.add("hello");
        list.add("java");
        list.add("world");
        
        // 通过ListIterator迭代器 遍历元素
        // next hasNext
        ListIterator<String> lit = list.listIterator();
        // 此时游标的位置:游标 hello java world。
        while(lit.hasNext()){
            String s = lit.next();
            System.out.println(s);
        }
        //依次输出 hello,java,world

        System.out.println("---------------");
        // 此时游标的位置:hello java world 游标
        while(lit.hasPrevious()){
            String s = lit.previous();
            System.out.println(s);
        }
        //依次输出:world,java,hello

        //获取列表迭代器 遍历列表,比较是否有world,有则添加javaee元素
        ListIterator<String> lit2 = list.listIterator();
        //使用iterator方法返回的Iterator迭代器,采用List集合对象的add方法添加元素会报错,
        // 但是采用ListIterator迭代器的add方法则不会报错
        while (lit2.hasNext()) {
            String s = lit2.next();
            if(s.equals("world")){
                lit2.add("javaee");
            }
        }
        System.out.println(list);
        // [hello, java, world, javaee]
    }
}

源码分析:

Iterator<String> it = list.iterator();  分析步骤1
while (it.hasNext()) {
    String s = it.next();
    if(s.equals("world")){
        list.add("javaee");  分析步骤1
    }
}
// 使用迭代器遍历集合元素会报错:ConcurrentModificationException
System.out.println(list);
//获取列表迭代器 遍历列表,比较是否有world,有则添加javaee元素
ListIterator<String> lit2 = list.listIterator();

//使用iterator方法返回的Iterator迭代器,采用List集合对象的add方法添加元素会报错,
// 但是采用ListIterator迭代器的add方法则不会报错
while (lit2.hasNext()) {
    String s = lit2.next();
    if(s.equals("world")){
        lit2.add("javaee");
    }
}
System.out.println(list);
// [hello, java, world, javaee]

分析代码:
list集合通过Iterator迭代器遍历集合,会报错;
list集合通过ListIterator迭代器遍历集合,不会报错;

原因是:
private class ListItr extends Itr implements ListIterator 返回的是ListIterator的实现类对象 = ListItr对象
ListIterator迭代器返回ListItr 的对象,ListItr 类中的add方法,有变量modCount 赋值给 exceptedModCount的语句,这样执行checkForComodification();的时候,判断modCount和exceptedModCount变量不相等输出ConcurrentModificationException 的情况不成立。

1 首先是List接口,接着使用接口中定义的两个方法:iterator、Listiterator、add
public interface List<E> {
		Iterator<E> iterator();
		ListIterator<E> listIterator();
}

2 创建对象,new的是ArrayList这个实现类的对象 来解释iterator 和 ListIterator 的 区别

** ArrayList集合继承自 AbstractList
public abstract class AbstractList<E>{
	protected transient int modCount = 0;
	// 此变量在AbstractList<E>类中
}

** ArrayList
public class ArrayList<E> extends AbstractList<E>  implements List<E> {
	// ArrayList实现了List这个接口,就需要重写List中的方法,例如:iterator、add、Listiterator
		public ListIterator<E> listIterator() {
		   return new ListItr(0);
		}
	   public Iterator<E> iterator() {
	        return new Itr();
	    }
	    
		private class ListItr extends Itr implements ListIterator<E> {
		     public void add(E e) {
		         checkForComodification();
		         try {
		             int i = cursor;
		             ArrayList.this.add(i, e);
		             cursor = i + 1;
		             lastRet = -1;
		             expectedModCount = modCount;
		         } catch (IndexOutOfBoundsException ex) {
		             throw new ConcurrentModificationException();
		         }
		     }
    }

增强for循环

作用:
简化数组和Collection集合的遍历

概述:

  • Collection集合 继承自接口Iterable< E >
  • 实现Iterable接口的类允许其对象成为增强型for语句的目标。
  • 它是JDK5之后出现的,其内部原理是一个Iterator迭代器。

增强for格式

for(元素数据类型 变量名:数组或者Collection集合){
		// 在此处使用变量即可,该变量就是元素
}

案例:
int[] arr = {1,2,3,4,5};
for(int i : arr){
	System.out.println(i);
	}

案例:元素类型是:int、String、List集合

int[] arr = {1,2,3,4,5};
for(int i : arr){
    System.out.println(i);
}
//输出内容:1 2 3 4 5
System.out.println("----------");

String[] s = {"hello","java","world"};
for(String st : s){
    System.out.println(st);
}
//输出内容:hello、java、world
System.out.println("--------");

List<String> list = new ArrayList<String>();
list.add("world");
list.add("java");
for(String str : list){
    System.out.println(str);
}
// 输出内容:world  java

证明:增强for循环的内部原理是一个Iterator迭代器

// 通过在for循环中 添加元素 看是否抛出并发异常
for(String str : list){
    if(str.equals("world")){
        list.add("javaee");
    }
}
// 报错:抛出ConcurrentModificationException异常

案例:List集合存储学生对象三种方式遍历

// 29-test3
public class StudentDemo {
    public static void main(String[] args) {

        List<Student> list = new ArrayList<Student>();

        Student s1 = new Student("汪苏泷",33);
        Student s2 = new Student("易烊千玺",20);
        Student s3 = new Student("胡夏",35);

        list.add(s1);
        list.add(s2);
        list.add(s3);

        //遍历元素
        // 方式一:迭代器 collection.iterator 还有迭代器的方法hasNext、next
        Iterator<Student> it = list.iterator();
        while(it.hasNext()){
            Student stu = it.next();
            System.out.println(stu.getName() + ", " + stu.getAge());
        }
        System.out.println("1-----------");
        
        // 方式二:普通的for循环 List.get list.size()
        for(int i = 0 ; i< list.size(); i ++){
            Student stu = list.get(i);
            System.out.println(stu.getName() + ", "+stu.getAge());
        }
        System.out.println("2---------------");
        
        // 方式三:增强for循环
        for(Student stu : list){
            System.out.println(stu.getName() + ", "+stu.getAge());
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值