集合——List

List

1. 概述 & 特点

1.1 概述

  • 有序集合(序列),用户可以精确控制列表中每个元素的插入位置
  • 用户可以通过整数索引访问元素,并搜索列表中的元素
  • 与Set集合不同,列表通常允许重复的元素

1.2 特点

  • 有索引
  • 可以存储重复元素
  • 元素存储有序

2. 特有方法

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

2.1 add() & remove()

public class Demo {
    public static void main(String[] args) {
        //创建集合对象
        List<String> list = new ArrayList<String>();
        //添加元素
        list.add("hello");
        list.add("world");
        list.add("world");
        System.out.println(list);
        
        //调用void add(int index,E element) 在指定位置插入指定元素
        list.add(1,"hahah"); //索引是从0开始的
        System.out.println(list);
        
        //调用E remove(int index) 删除指定索引处的元素,返回被删除的元素
        System.out.println(list.remove(1));
        System.out.println(list);
    }
}
/* 输出结果
[hello, world, world]
[hello, hahah, world, world]
hahah
[hello, world, world] */

2.2 set() & get()

public class Demo {
    public static void main(String[] args) {
        //创建集合对象
        List<String> list = new ArrayList<String>();
        list.add("hello");
        list.add("world");
        list.add("world");
        System.out.println(list); //[hello, world, world]

        //调用E set(int index,E element)方法 修改指定位置的元素,返回被修改的元素
        System.out.println(list.set(1,"hahaha")); //world
        System.out.println(list); //[hello, hahaha, world]

        //调用E get(int index)方法,返回指定位置的元素
        System.out.println(list.get(1)); //hahaha
    }
}
/* 输出结果
[hello, world, world]
world
[hello, hahaha, world]
hahaha  */

2.3 案例

2.3.1 List集合存储学生对象并遍历
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

//List集合存储学生对象并遍历
/*
1. 定义学生类
2. 创建list集合对象
3. 创建学生对象
4. 把学生添加到集合
5. 遍历集合
     遍历方法1. 迭代器方式
     for 循环方法
 */
public class Test01 {
    public static void main(String[] args) {
        //创建list集合对象
        List<Student> list = new ArrayList<Student>();

        //创建学生对象
        Student s1 = new Student("哈哈哈", 12);
        Student s2 = new Student("嘻嘻嘻", 13);
        Student s3 = new Student("吼吼吼", 14);
        //将学生对象添加到集合
        list.add(s1);
        list.add(s2);
        list.add(s3);

        //遍历集合 1.使用迭代器方式 在Collection中学到迭代器
        Iterator<Student> iterator = list.iterator();
        while (iterator.hasNext()){
            Student s = iterator.next();
            System.out.println(s.getName() + "," + s.getAge());
        }
        System.out.println("================");

        //遍历集合 2.使用for循环 + get()方法
        for (int i = 0; i < list.size(); i++) {
            //利用get()方法返回指定索引处元素
            Student s = list.get(i);
            System.out.println(s.getName() + "," + s.getAge());
        }

    }
}
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;
    }
}

4. 并发修改异常

4.1 异常原因

4.1.1 说明
  • 迭代器遍历的过程中,通过集合对象修改了集合中的元素,造成了迭代器获取元素中判断预期修改值和实际修改值不一致
    • 预期修改值:expectedModCount
    • 实际修改值:modCount
4.1.2 代码示例
public class Demo03 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();

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

        Iterator<String> iterator = list.iterator();
        //进行以下操作或出现 并发修改异常 ConcurrentModificationException
        while (iterator.hasNext()){
            String s = iterator.next();
            if(s.equals("world")){
                list.add("java");
            }
        }
        System.out.println(list); 
    }
}

4.2 解决方法

4.2.1 说明
  • 利用for循环遍历,然后用集合对象做对应操作
4.2.2 代码示例
import java.util.ArrayList;
import java.util.List;

public class Demo03 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();

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

        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            if (s.equals("hello")){
                //注意,如果添加的元素与判断元素相同 ,会导致死循环
                list.add(i+1,"hahaha"); // 这里i+1 表示在 hello 后面添加元素
            }
        }
        System.out.println(list);
    }
}

5. ListIterator<列表迭代器>

5.1 介绍

  • 通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器

  • 用于允许程序员沿任一方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置

5.2 常用方法

方法名说明
E next()返回迭代中的下一个元素
boolean hasNext()如果迭代具有更多元素,则返回 true
E previous()返回列表中的上一个元素
boolean hasPrevious()如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回 true
void add(E e)将指定的元素插入列表
5.2.1 代码示例
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Demo04 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
         list.add("hello");
         list.add("world");

        ListIterator<String> lit = list.listIterator();
        //正向遍历 比较少使用列表迭代器 一般使用iterator
        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);
        }

        while (lit.hasNext()){
            String s = lit.next();
            if (s.equals("hello")){
                //区别与迭代器,列表迭代器在进行此操作时不会发生并发修改异常
                lit.add("haha");//这个时候箭头应该位于hello下方,所以是在hello后插入指定元素
            }
        }
        System.out.println(list);
    }
}
/* 输出结果
hello
world
==============
world
hello
[hello, haha, world] */
5.2.2 注意点

image-20210813172741105

  • 正向遍历 hasNext() & next()

    • 第一次循环,箭头位于"hello"上方,所以next()返回迭代中的下一个元素,就会返回"hello",箭头移至"world"上方
    • 第二次循环,箭头位于"world"上方,所以调用方法输出的是"world",箭头移至world下方
    • hasNext()方法判断没有元素,返回false,结束while循环
    • 一般会直接使用迭代器进行遍历,较少使用列表迭代器
  • 反向遍历 hasPrevious() & previous()

    • 流程与正向遍历相同,但是最初箭头是在"hello"的上方,所以如果直接进行反向遍历,hasPrevious()会返回false,导致控制台没有输出结果
    • 这种方法用的少,所以理解就可以

6. 遍历集合的三种方法<总结>

6.1 说明

  • 使用 迭代器方法 遍历结合

  • 使用 for循环 + get() 方法 遍历集合

  • 使用增强For循环遍历集合

    • //增强For循环
      for(元素数据类型 变量名 : 数组/集合对象名){
          循环体
      }
      

6.2 代码示例

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class AddDemo {
    public static void main(String[] args) {
        //创建集合对象
        List<String> list = new ArrayList<String>();
        list.add("hello");
        list.add("world");
        System.out.println(list);
        
        //迭代器
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("=================");
        //for + get()
        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);
        }
    }
}

7. 数据结构

7.1 栈 &队列

  • 栈:先进后出
  • 队列:先进先出

7.2 数组 & 链表

  • 数组:查询快,增删慢
  • 链表:查询慢,增删快

8. List集合的实现类<子类>

8.1 子类

名称说明
ArrayList集合底层数据结构是数组,查询快,增删慢
LinkedList集合底层数据结构是链表,查询慢,增删快

8.1.1 ArrayList集合

//创建ArrayList集合对象
ArrayList<String> array = new ArrayList<String>();

8.1.2 LinkedList集合

8.1.2.1 特有方法
方法名说明
public void addFirst(E e)在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素
8.1.2.2 代码示例
import java.util.ArrayList;
import java.util.LinkedList;

public class LinkedListDemo {
    public static void main(String[] args) {
        //创建集合对象
        LinkedList<String> linkedList = new LinkedList<>();

        linkedList.add("hello");
        linkedList.add("world");
        System.out.println(linkedList);

        System.out.println("============:");
        //public void addFirst(E e) 在该列表开头插入指定的元素
        linkedList.addFirst("1java1");
        System.out.println(linkedList);
        System.out.println("============");
        //public void addLast(E e) 将指定的元素追加到此列表的末尾
        linkedList.addLast("2java2");
        System.out.println(linkedList);
        System.out.println("============");

        //public E getFirst() 返回此列表中的第一个元素
        System.out.println(linkedList.getFirst());
        System.out.println("============");
        //public E getLast() 返回此列表中的最后一个元素
        System.out.println(linkedList.getLast());
        System.out.println("============");

        //public E removeFirst() 从此列表中删除并返回第一个元素
        System.out.println(linkedList.removeFirst());
        System.out.println(linkedList);
        System.out.println("============");
        //public E removeLast() 从此列表中删除并返回最后一个元素
        System.out.println(linkedList.removeLast());
        System.out.println(linkedList);
    }
}
//输出结果
[hello, world]    //最初集合的元素
============
[1java1, hello, world]  //调用addFirst(E e)方法
============
[1java1, hello, world, 2java2] //调用addLast(E e)方法
============
1java1  //调用getFirst()方法
============
2java2  //调用getLast()方法
============
1java1  //调用removeFirst()方法
[hello, world, 2java2]
============
2java2  //调用removeLast()方法
[hello, world]
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值