三十二、Java集合(一)——Collection与List全家桶

Collection 单列集合与 List 全家桶 🔥

数组长度固定、功能太少?遇到动态数据就头大?

学完数组的定长限制后,Java 集合就是来解决这个问题的万能伸缩容器 🎒。

今天我们先搞定Collection 接口List 集合,小白也能一次学会!


一、Collection 单列集合「顶层老大」📦

idea 快捷键itit → 快速生成迭代器 while 循环

1.1 核心概念

  1. Collection所有单列集合的顶层接口 ,它定义了单列集合的共性行为
  2. JDK 不提供它的直接实现,而是通过更具体的子接口(List、Set)实现。
  3. 创建 Collection 集合采用多态方式
java 复制代码
// 接口类型引用指向实现类对象,仅可调用Collection方法
Collection c = new ArrayList();

1.2 Collection 常用方法(必会 )

方法原型 功能说明
add(Object o) 向集合添加元素,返回 boolean,true 成功、false 失败
remove(Object o) 删除指定元素,返回 boolean,true 删除成功
clear() 清空集合所有元素,对象还在,无返回值
contains(Object o) 判断是否包含指定元素,返回 true / false
isEmpty() 判断集合是否为空(元素为0),空集合≠null ⚠️
size() 获取集合元素个数(集合长度)
toArray() 将集合元素转为 Object[] 数组并返回

1.3 示例代码(带注释,可直接复制运行 )

java 复制代码
public class Demo01 {
    public static void main(String[] args) {
        // 1. 创建Collection集合(多态写法)
        Collection c = new ArrayList();

        // 2. 添加元素(基本类型自动装箱为包装类)
        c.add("1");
        c.add("这周又要愉快的结束了");
        c.add("恭喜大家明天还要自习");
        c.add('c');

        // 3. 打印集合
        System.out.println("集合里的元素:" + c);
        // 输出:集合里的元素:[1, 这周又要愉快的结束了, 恭喜大家明天还要自习, c]

        // 4. 判断是否包含指定元素
        System.out.println("集合里有1吗?" + c.contains(1)); // false(存的是字符串"1")
        // 输出:集合里有1吗?false
        System.out.println("集合里有'c'吗?" + c.contains('c')); // true
        // 输出:集合里有'c'吗?true

        // 5. 删除元素
        System.out.println("删除'c'成功了吗?" + c.remove('c')); // true
        // 输出:删除'c'成功了吗?true
        System.out.println("删除后的集合:" + c);
        // 输出:删除后的集合:[1, 这周又要愉快的结束了, 恭喜大家明天还要自习]

        // 6. 获取集合长度
        System.out.println("集合里有多少个元素?" + c.size());
        // 输出:集合里有多少个元素?3

        // 7. 集合转数组并遍历
        Object[] o = c.toArray();
        for (int i = 0; i < o.length; i++) {
            String s = (String) o[i]; // 向下转型为String
            System.out.println("数组中的元素:" + s);
            System.out.println("元素长度:" + s.length());
        }
    }
}

二、实战:集合存自定义对象并遍历 🏗️

需求:定义人类(姓名、年龄),存入集合,遍历获取每个人的姓名。

java 复制代码
public class Demo02 {
    public static void main(String[] args) {
        Collection c = new ArrayList();
        c.add(new Person("小王八", 11));
        c.add(new Person("小黄吧", 22));
        c.add(new Person("小黑吧", 33));
        c.add(new Person("小陈八", 44));

        Object[] o = c.toArray();
        for (int i = 0; i < o.length; i++) {
            Person p = (Person) o[i];
            System.out.println(p.getName());
        }
    }
}

class Person {
    private String name;
    private int age;

    public Person() {}

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', 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; }
}

三、单列集合 3 种遍历方式(必会 🔄)

3.1 迭代器遍历(最通用)

迭代器是单列集合专用遍历工具

获取迭代器:

java 复制代码
Iterator it = 集合.iterator();

方法:

  • hasNext():判断有没有下一个元素
  • next():取出元素并移动指针
  • remove():删除当前元素(迭代器自带)
java 复制代码
public class Demo03 {
    public static void main(String[] args) {
        Collection c = new ArrayList();
        c.add("a");
        c.add("b");
        c.add("c");
        c.add("d");
        c.add("f");

        Iterator it = c.iterator();
        while (it.hasNext()) {
            Object next = it.next();
            System.out.println(next);
        }
    }
}

3.2 增强 for 循环(最简单 ⭐)

快捷键I(大写 i)

底层就是迭代器,写法最简洁。

java 复制代码
public class Demo04 {
    public static void main(String[] args) {
        // 1. 创建集合并添加元素
        Collection c = new ArrayList();
        c.add("a");
        c.add(123);  // 自动装箱成Integer
        c.add('c');   // 自动装箱成Character

        // 2. 增强for循环遍历(格式:for(元素类型 变量名 : 集合))
        for (Object o : c) {
            System.out.println(o);
        }

        // 拓展:增强for也可遍历数组
        int[] arr = {1, 23, 4, 5};
        for (int i : arr) {
            System.out.println(i);
        }
    }
}

3.3 普通 for 循环(仅 List 可用 📋)

因为 List 有索引,所以可以用普通 for。


四、有序 List 集合 📋

Collection 子接口List 继承 Collection 的所有方法,额外提供索引相关的专属功能。

4.1 List 特点

  1. 有序 ✅:存入顺序与取出顺序完全一致。
  2. 有索引 🔢:元素有位置编号,从0开始(与数组规则一致)。
  3. 可重复 🔄:同一元素可多次存入集合。

4.2 List 特有方法

方法原型 功能说明
add(int index, Object o) 指定位置插入
remove(int index) 按索引删除
set(int index, Object o) 替换元素
get(int index) 根据索引获取
subList(from, to) 截取子集合(含头不含尾)

4.3 List 遍历(普通 for + get)

java 复制代码
public class Demo05 {
    public static void main(String[] args) {
        // 1. 创建List集合(多态写法)
        List l = new ArrayList();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("d");

        // 2. 普通for循环遍历(索引范围:0 ~ 集合.size()-1)
        for (int i = 0; i < l.size(); i++) {
            Object o = l.get(i); // 根据索引获取元素
            System.out.println("普通for遍历的元素:" + o);
        }
    }
}

五、并发修改异常(高频坑点 ⚠️)

异常ConcurrentModificationException

原因
迭代器遍历的时候,用集合对象增删元素

解决方法

  1. 使用迭代器自带的 remove()
  2. 使用普通 for 循环遍历
  3. 使用 ListIterator(支持增删)
java 复制代码
public class Demo06 {
    public static void main(String[] args) {
        List l = new ArrayList();
        l.add(new Person("张三", 18));
        l.add(new Person("李四", 20));
        l.add(new Person("王五", 28));
        l.add(new Person("书源", 38));

        for (int i = 0; i < l.size(); i++) {
            Person p = (Person) l.get(i);
            if (p.getName().equals("李四")) {
                l.remove(p);  // ✅ 普通for循环中可以
            }
        }
        System.out.println(l);
    }
}

六、ArrayList 与 LinkedList 区别 ⚡

6.1 ArrayList(数组实现 📦)

  • ArrayList 中维护了有个 Object 类型的数组(elementData数组
  • 查询快、增删慢 🔍
  • 初始容量 0 → 第一次添加扩容 elementData 为 10 → 再次扩容 elementData 的 1.5 倍

简单说 :ArrayList 是 List 的实现类,没有特有的方法,学习其特点即可,数组实现,增删慢,查改快

实际开发中,ArrayList 用的最多,很多功能都需要用到统计查询。

java 复制代码
public class Demo07 {
    public static void main(String[] args) {
        // ArrayList没有特有的方法,使用List下的方法
        ArrayList list = new ArrayList();
        list.add("123");
    }
}
补充:Vector(早期实现 🕰️)

① Vector 出现早,效率慢,多线程安全

② ArrayList 出现晚,效率高,多线程不安全

Vector 使用特点和 ArrayList 一致,但已不推荐新项目使用。

6.2 LinkedList(双向链表 🔗)

  • 增删快、查询慢
  • 该类型有大量的对于头部、尾部操作的方法

常用方法

方法 功能
addFirst(E e) 向头部添加元素
addLast(E e) 向尾部添加元素
getFirst() 获取头部元素
getLast() 获取尾部元素
removeFirst() 删除头部元素
removeLast() 删除尾部元素
java 复制代码
LinkedList l = new LinkedList();
l.addFirst("书源");
l.addLast("田六");
System.out.println(l.getFirst());  // 书源
System.out.println(l.getLast());   // 田六

6.3 面试常问 💼

Q1:为什么 ArrayList 查改快、增删慢?

因为底层是数组,有索引直接定位;增删需要移动大量元素。

Q2:为什么 LinkedList 增删快?

因为底层是链表,只需要修改指针指向,不需要移动元素。

6.4 性能测试(感兴趣的可以跑一下 🏃)

java 复制代码
public class Demo08 {
    public static void main(String[] args) {
        test_尾部添加();
        test_头部添加();
        test_获取元素();
    }

    private static void test_尾部添加() {
        long l1 = System.currentTimeMillis();
        ArrayList l = new ArrayList();
        for (int i = 0; i < 100000; i++) {
            l.add(i);
        }
        long l2 = System.currentTimeMillis();
        System.out.println("ArrayList尾部添加十万个元素:" + (l2 - l1) + "ms");

        long l3 = System.currentTimeMillis();
        LinkedList lk = new LinkedList();
        for (int i = 0; i < 100000; i++) {
            lk.addLast(i);
        }
        long l4 = System.currentTimeMillis();
        System.out.println("LinkedList尾部添加十万个元素:" + (l4 - l3) + "ms");
    }

    private static void test_头部添加() {
        long l1 = System.currentTimeMillis();
        ArrayList l = new ArrayList();
        for (int i = 0; i < 100000; i++) {
            l.add(0, i);
        }
        long l2 = System.currentTimeMillis();
        System.out.println("ArrayList头部添加十万个元素:" + (l2 - l1) + "ms");

        long l3 = System.currentTimeMillis();
        LinkedList lk = new LinkedList();
        for (int i = 0; i < 100000; i++) {
            lk.addFirst(i);
        }
        long l4 = System.currentTimeMillis();
        System.out.println("LinkedList头部添加十万个元素:" + (l4 - l3) + "ms");
    }

    private static void test_获取元素() {
        ArrayList l = new ArrayList();
        for (int i = 0; i < 200000; i++) {
            l.add(0, i);
        }
        long l1 = System.currentTimeMillis();
        for (int i = 0; i < l.size(); i++) {
            l.get(i);
        }
        long l2 = System.currentTimeMillis();
        System.out.println("ArrayList获取十万个元素:" + (l2 - l1) + "ms");

        LinkedList lk = new LinkedList();
        for (int i = 0; i < 200000; i++) {
            lk.addFirst(i);
        }
        long l3 = System.currentTimeMillis();
        for (int i = 0; i < lk.size(); i++) {
            lk.get(i);
        }
        long l4 = System.currentTimeMillis();
        System.out.println("LinkedList获取十万个元素:" + (l4 - l3) + "ms");
    }
}

本篇总结 📝

  1. Collection:单列集合顶层接口,定义了增删查改等共性方法 📦
  2. List:有序、有索引、可重复,主要实现类有 ArrayList 和 LinkedList 📋
  3. 遍历方式:迭代器、增强 for、普通 for(仅 List)🔄
  4. 坑点:并发修改异常,迭代时别用集合增删 ⚠️
  5. ArrayList vs LinkedList
    • ArrayList:数组实现,查改快,增删慢 🔍
    • LinkedList:链表实现,增删快,查询慢 ⚡

🚀 下一篇预告:《三十三、Java集合(二)------Set集合与Collections工具类》------ 搞定 HashSet、TreeSet 去重排序,还有 Collections 工具类一把梭!


作者 :书源丶
发布平台 :CSDN
系列:「Java基础篇」

相关推荐
一个人旅程~1 小时前
Win旧版或win10部分版本如何解除260字符长路径名限制?
linux·windows·经验分享·电脑
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题】【Java基础篇】第21题:HashMap和Hashtable的区别是什么
java·开发语言·面试·哈希算法·散列表·hash table
慕容卡卡1 小时前
Claude 使用神器(web页面)--CloudCLI UI
java·开发语言·前端·人工智能·ui·spring cloud
Sylvia-girl1 小时前
C++内存如何管理?
java·jvm·c++
极创信息1 小时前
信创领域五种主流CPU架构(X86 / ARM / RISC-V / MIPS / LoongArch)
java·arm开发·数据库·spring boot·mysql·软件工程·risc-v
_日拱一卒2 小时前
LeetCode:146LRU缓存
java·开发语言
StockTV2 小时前
韩国股票实时数据 KOSPI(主板)和 KOSDAQ(创业板)的实时行情、K 线及指数数据
java·开发语言·算法·php
Java成神之路-2 小时前
面试题:SpringMVC执行流程(视图版+前后端分离版)
java·springmvc