【集合系列】List集合

本文详细介绍了Java中的List集合,包括其特性、常用的特有方法(如add、remove、set和get),以及各种遍历方式(迭代器、列表迭代器、增强for、Lambda表达式和普通for循环)。同时,强调了注意事项,如equals方法的使用、ArrayList和LinkedList的选择,以及避免在循环中修改集合以防止异常。
摘要由CSDN通过智能技术生成

其他集合类

父类Collection类

集合类的遍历方式

具体信息请查看 API 帮助文档

实现类:ArrayListLinkedListVector (现已淘汰)

1. 概述

List是Java中一种常用的数据结构,它是一种有序的集合,可以存储任意类型的对象。

List允许重复的元素,并且可以根据索引位置访问和操作元素。它提供了一系列方法来添加、删除、获取和修改元素,以及其他一些常见的操作,比如查找、排序等。

List是一个接口,Java提供了多个实现List接口的类,常见的有ArrayList和LinkedList。

  • ArrayList是基于数组实现的,它的查询效率较高,但插入和删除元素的效率较低。

  • LinkedList是基于链表实现的,它的插入和删除元素的效率较高,但查询效率较低。

List接口:(因为List是一个接口,因此不能创建List的对象,而要创建它的实现类的对象)

  1. 有序集合,这里的有序指的是存取顺序

  2. 用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素

  3. 与Set集合不同,列表通常允许重复的元素

集合的特点

  1. 存取有序

  2. 可以重复

  3. 有索引

2. 方法

因为List是Collection集合的子类,因此Collection集合中的方法,List集合都可以使用。

Collection集合类

2.1 特有方法

特有方法介绍:

方法描述
void add(int index, E element)在指定位置插入指定元素
E remove(int index)删除指定索引处的元素, 返回被删除元素
E set(int index, E element)修改指定索引处的元素, 返回被修改的元素
E get(int index)返回指定索引处的元素

注意点

  • void add(int index,E element) 在此集合中的指定位置插入指定的元素

    • 细节:集合中的原有元素会依次后移
  • E remove(int index) 删除指定索引处的元素,返回被删除的元素

    • 细节:删除元素有两个方法,一是直接通过元素内容删除,二是根据索引删除。

    • 如果创建的集合类型是Integer类型的,那删除元素是根据元素内容删除还是根据索引删除?

    • 结果是根据索引进行删除的,因为在调用方法的时候,如果方法出现了重载现象,优先调用的是实参跟形参一致的那个方法。

    1是int类型的,而根据索引删除的方法里的形参也是int类型,根据内容删除的则是Integer类型,则需要装箱,因此调用的是根据索引进行删除的方法

    • 假如非要根据内容进行删除,则需进行手动装箱(此时remove方法是不会自动装箱的),把基本数据类型1,变成Integer类型

2.2 代码示例

  • 代码示例
package text.text02;

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

/*
List接口:(因为List是一个接口,因此不能创建List的对象,而要创建它的实现类的对象)
    有序集合,这里的有序指的是存取顺序
    用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素
    与Set集合不同,列表通常允许重复的元素

集合的特点:
    1.存取有序
    2.可以重复
    3.有索引

 */
public class text27B {
    public static void main(String[] args) {
        //创建集合对象并添加元素
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        System.out.println("========== 创建集合对象并添加元素  ==========");
        System.out.println(list);      //[aaa, bbb, ccc, ddd]


        System.out.println();


        //void add(int index,E   element)   在此集合中的指定位置插入指定的元素
        //细节:集合中的原有元素会依次后移
        System.out.println("========== void add(int index,E   element) :在此集合中的指定位置插入指定的元素  ==========");
        list.add(3, "eee");
        System.out.println(list);       //[aaa, bbb, ccc, eee, ddd]


        System.out.println();


        //E remove(int   index)             删除指定索引处的元素,返回被删除的元素
        System.out.println("========== E remove(int   index) : 删除指定索引处的元素,返回被删除的元素  ==========");
        String remove1 = list.remove(3);
        System.out.println("删除的元素是:" + remove1);      //删除的元素是:eee
        System.out.println(list);           //[aaa, bbb, ccc, ddd]

        System.out.println();

        //细节:删除元素有两个方法,一是直接通过元素内容删除,二是根据索引删除。
        //如果创建的集合类型是Integer类型的,那删除元素是根据元素内容删除还是根据索引删除?
        System.out.println("----- 删除元素的两个方法 -----");
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        Integer remove2 = list1.remove(1);
        System.out.println("删除的元素是:" + remove2);      //删除的元素是:2
        System.out.println("根据索引删除:" + list1);     //根据索引删除:[1, 3] 由此可知是根据索引进行删除的,因为在调用方法的时候,如果方法出现了重载现象,优先调用的是实参跟形参一致的那个方法。(1是int类型的,而根据索引删除的方法里的形参也是int类型,根据内容删除的则是Integer类型,则需要装箱,因此调用的是根据索引进行删除的方法)

        list1.add(1, 2);

        //假如非要根据内容进行删除,则需进行手动装箱(此时remove方法是不会自动装箱的),把基本数据类型1,变成Integer类型
        Integer i = Integer.valueOf(1);
        boolean remove3 = list1.remove(i);
        System.out.println("1是否成功删除:" + remove3);       //1是否成功删除:true
        System.out.println("根据内容进行删除:" + list1);    //根据内容进行删除:[2, 3]


        System.out.println();


        //E set(int index,E   element)      修改指定索引处的元素,返回被修改的元素
        System.out.println("========== E set(int index,E   element) : 修改指定索引处的元素,返回被修改的元素  ==========");
        String set = list.set(1, "sss");
        System.out.println("修改的元素是:" + set);        //修改的元素是:bbb
        System.out.println(list);     //[aaa, sss, ccc, ddd]


        System.out.println();


        //E get(int   index)                返回指定索引处的元素
        System.out.println("========== E get(int   index):返回指定索引处的元素  ==========");
        String get = list.get(0);
        System.out.println("该索引位置的元素是:" + get);        //该索引位置的元素是:aaa
        System.out.println(list);           //[aaa, sss, ccc, ddd]
    }
}

  • 输出结果
    在这里插入图片描述

3. 遍历方式

3.1 迭代器

与共有的 集合遍历方式 一样

3.2 列表迭代器 (特有)

列表迭代器(ListIterator)是Java集合框架中提供的一种专门用于迭代访问List集合的迭代器。

与普通迭代器(Iterator)相比,列表迭代器提供了更多的功能。它不仅可以向前遍历集合,还可以向后遍历集合,还可以在迭代过程中对元素进行添加、修改、删除等操作。

特点常用方法
双向遍历- boolean hasPrevious(): 判断是否有前一个元素
- E previous(): 获取前一个元素
- boolean hasNext(): 判断是否有后一个元素
- E next(): 获取后一个元素
修改元素- void set(E e): 修改当前所指向的元素
添加元素- void add(E e): 在当前位置之前添加元素
删除元素- void remove(): 删除当前所指向的元素
元素索引- int previousIndex(): 获取前一个元素的索引
- int nextIndex(): 获取后一个元素的索引
可选操作- int nextIndex(): 获取迭代器的当前索引位置
- void forEachRemaining(Consumer<? super E> action): 对剩余的元素应用给定的操作

使用列表迭代器的一般步骤是,首先通过调用listIterator()方法获取列表迭代器的实例,然后通过调用next()方法来遍历集合,使用hasNext()方法来判断是否有下一个元素。

3.3 增强for

与共有的 集合遍历方式 一样

3.4 Lambda表达式

与共有的 集合遍历方式 一样

3.5 普通for循环

List集合有索引,其中原理是利用size()方法、get()方法和循环遍历获得元素

格式:

for (int i = 0; i < list.size(); i++) {
           String str = list.get(i);
           System.out.println(str);    
       }

3.6 遍历方式的对比

  1. 迭代器:

    • 适用于遍历任何实现了Iterable接口的集合类。

    • 提供了hasNext()和next()方法,通过循环调用这两个方法来遍历集合。

    • 可以在遍历过程中移除集合中的元素。

  2. 列表迭代器(特有):

    • 是迭代器的一种,专门用于遍历List集合。

    • 可以双向遍历,通过previous()方法向前遍历,通过next()方法向后遍历。

    • 提供了set()方法用于修改当前元素,add()方法用于在当前位置之前添加元素,remove()方法用于删除当前元素。

  3. 增强for循环:

    • 适用于遍历数组和实现了Iterable接口的集合类。

    • 提供了简洁的语法,不需要手动获取迭代器或使用索引来访问元素。

    • 只能进行正向遍历,无法做到修改或删除元素。

  4. Lambda表达式:

    • 适用于遍历实现了Iterable接口的集合类。

    • 通过Lambda表达式和函数式接口(如Consumer接口)实现遍历和对元素的操作。

    • 可以将遍历和操作的逻辑集中在一起,简化代码。

  5. 普通for循环:

    • 可以用于遍历数组和集合类。

    • 可以根据需要进行正向或反向遍历。

    • 可以通过索引访问元素,且可以根据需要修改或删除元素。

3.7 代码示例

  • 代码示例
package text.text02;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Consumer;

/*
List集合的遍历方式:
   1. 迭代器
   2. 列表迭代器 (特有)
   3. 增强for
   4. Lambda表达式
   5. 普通for循环 (因为List集合有索引,其中原理是利用size()方法、get()方法和循环遍历获得元素)
*/
public class text28A {
   public static void main(String[] args) {
       //创建集合并添加元素
       List<String> list = new ArrayList<>();
       list.add("aaa");
       list.add("bbb");
       list.add("ccc");
       list.add("ddd");

       // 1. 迭代器
       Iterator<String> it1 = list.iterator();
       System.out.print("迭代器遍历:");
       while (it1.hasNext()) {
           String str1 = it1.next();
           //删除元素ccc
           if ("ccc".equals(str1)) {
               it1.remove();
           }
       }
       System.out.print(list);     //迭代器遍历:[aaa, bbb, ddd]


       System.out.println();


       //2. 列表迭代器 (特有)
       ListIterator<String> it2 = list.listIterator();
       System.out.print("列表迭代器:");
       while (it2.hasNext()) {
           String str2 = it2.next();
           //添加元素
           if ("bbb".equals(str2)) {
               it2.add("CCC");
           }
       }
       System.out.print(list);      //列表迭代器:[aaa, bbb, CCC, ddd]


       System.out.println();


       //  3. 增强for
       System.out.print("增强for遍历:");
       //s是第三方变量,依次表示集合中遍历到的的每一个元素
       for (String s : list) {
           System.out.print(s + " ");      //增强for遍历:aaa bbb CCC ddd
       }


       System.out.println();


       //  4. Lambda表达式
       System.out.print("Lambda表达式遍历:");
       list.forEach((s) -> System.out.print(s + " "));       //Lambda表达式遍历:aaa bbb CCC ddd


       System.out.println();


       //  5. 普通for循环
       System.out.print("普通for循环遍历:");
       for (int i = 0; i < list.size(); i++) {
           String str3 = list.get(i);
           System.out.print(str3 + "  ");      //普通for循环遍历:aaa  bbb  CCC  ddd
       }
   }
}

  • 输出结果
    在这里插入图片描述

4. 注意事项

  1. List是一个有序的集合,它允许重复的元素。这意味着可以按照插入顺序访问和操作元素,也可以使用索引来获取和修改元素。但是需要注意,List对于元素的比较是通过equals()方法来判断的,所以确保你的元素类正确实现了equals()方法。

  2. 当使用ArrayList实现List时,插入和删除元素的效率较低。当需要频繁地在集合的中间位置插入和删除元素时,可以考虑使用LinkedList,它的插入和删除元素的效率较高。

  3. 在使用List的过程中要注意索引的范围,避免越界访问。List的索引从0开始,到size()-1结束。

  4. List集合是可变的,可以动态地增加或删除元素。当需要在集合的任意位置插入或删除元素时,可以使用add()和remove()方法。

  5. 考虑集合中的元素数量以及对性能的影响。在大量的数据操作中,使用ArrayList的性能通常比LinkedList要好。

  6. 使用循环遍历或迭代器遍历List集合时要注意避免在循环内部进行集合的增删操作,这可能导致ConcurrentModificationException异常。

  7. List集合也支持其他操作,比如查找元素、排序元素等。可以使用contains()方法来判断集合中是否包含某个元素,使用sort()方法对集合进行排序等。

  • 21
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

酷小洋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值