Day26 | Java集合框架概览

经过前面25天的学习,我们已经打下了Java的语言基础。

从今天起,我们进入一个全新的、至关重要的领域------Java集合框架。

一、什么是集合框架

在没有集合框架之前,如果你需要存储一组学生对象,你可能会使用数组。

但数组有一个致命的缺陷:长度一旦确定,就没办法改变了。

定义短了,可能不够用,定义长了,又可能造成资源浪费。

为了解决这类问题,Java提供了一套性能优良、使用方便的API,用来表示和操作对象的集合。

可以把它看成一个收纳万物的"工具箱",里面有各种各样的"容器"(比如列表、集合、队列、映射表等),可以高效地对数据进行增、删、改、查等操作。

为什么Java要给我们提供这些集合框架?

很多复杂的数据结构,你如链表、哈希表、红黑树等,Java集合框架已经帮我们实现好了,而且经过了一定的优化,不再需要我们从零开始实现这些结构,方便我们的使用。

这些数据结构是我们在日常开发中比较常使用的,集合框架都经过了精心设计和优化,通常情况下比我们自己去现写的要高效得多。

集合框架提供了一套标准化的接口,不管具体的实现是什么,或者发生什么变化,操作这些集合的方法都是一致的,我们在学习和使用的时候,成本都比较低。

二、Java集合框架图谱

Java集合框架主要由两个核心接口分支构成,它们是所有集合类的"老祖宗":

2.1 Collection

ArrayList

HashSet

PriorityQueue

上面的ArrayList、HashSet、PriorityQueue都实现了一个共同的接口Collection。

Collection是存放独立元素的集合的根接口。它的特点就是,容器里的每个位置只存放一个元素。

Collection有三个主要的子接口:List、Set、Queue。

List是一个有序的集合,允许存放重复的元素。你可以像操作数组一样通过索引来访问元素。(代表实现:ArrayList, LinkedList)

Set是一个不重复元素的集合。它不保证元素的顺序(某些实现类除外)。(代表实现:HashSet, TreeSet)

Queue是一个按特定规则(通常是先进先出FIFO)来处理元素的集合。(代表实现:LinkedList, PriorityQueue)

2.2 Map

HashMap

Map是存放键值对的集合的根接口。

Map里的每个元素都包含一个唯一的键(Key)和一个值(Value)。

它不继承自Collection接口,自成一派。(代表实现:HashMap, TreeMap)

三、Collection的核心能力

Collection接口定义了所有单元素集合都必须具备的通用方法。

掌握了它,你就掌握了操作List、Set、Queue的一半了。

一起简单的梳理下Collection中定义的属性和行为:

java 复制代码
public interface Collection<E> extends Iterable<E> {
// 集合里装的元素个数
int size();

// 集合是不是空的
boolean isEmpty();

// 集合里是不是包含某个对象
boolean contains(Object o);

// 返回一个用来遍历集合的迭代器
Iterator<E> iterator();

// 把集合转换成一个Object数组
Object[] toArray();

// 把集合转换成一个指定类型的数组
<T> T[] toArray(T[] a);

// 添加一个元素到集合里
boolean add(E e);

// 从集合里移除一个元素
boolean remove(Object o);

// 把另一个集合的所有元素都添加到这个集合
boolean addAll(Collection<? extends E> c);

// 移除集合里也存在于另一个集合中的所有元素
boolean removeAll(Collection<?> c);

// 清空集合里的所有元素
void clear();
}

Collection里的E就是我们之前学习的泛型,表示元素的类型。

四、Iterable和Iterator

你可能已经注意到,Collection接口继承了一个Iterable接口。

Iterable接口其实是Java 5引入的,它让实现了这个接口的集合都具备了使用for-each循环的能力。

我们在看继承关系的时候,看到able结尾的接口,大多数情况下下就可以理解成,让子类具有某项能力。

java 复制代码
public interface Iterable<E> {
    Iterator<E> iterator();
}

Iterator(迭代器) 可以看成真正负责遍历的指针。

类似一个游标,在集合上移动,并提供了安全地访问和删除元素的方法。

java 复制代码
public interface Iterator<E> {
// 判断集合里是不是还有下一个元素可以访问。
boolean hasNext();

// 返回集合里的下一个元素,并将"指针"后移一位。
E next();

}

提到删除元素,我们在初学的时候,还会遇到一个坑。

java 复制代码
package com.lazy.snail.day26;

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

/**
 * @ClassName Day26Demo
 * @Description TODO
 * @Author lazysnail
 * @Date 2025/6/23 13:42
 * @Version 1.0
 */
public class Day26Demo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("懒惰");
        list.add("蜗牛");
        list.add("Java");

        for (String str : list) {
            if ("懒惰".equals(str)) {
                list.remove(str);
            }
        }
    }
}

在调用list.remove()的时候,ArrayList的内部结构发生了变化(元素数量、索引等),但迭代器Iterator并不知道这个变化。

当迭代器继续下一次next()操作时,它会发现"账对不上了",然后马上就抛出ConcurrentModificationException(并发修改异常)来防止后面可能发生更严重的数据错乱问题。

推荐的遍历删除方式就是使用迭代器的remove()方法:

java 复制代码
Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String str = iterator.next();
            if ("懒惰".equals(str)) {
                iterator.remove();
            }
        }

iterator.remove()会通知集合本次修改,确保数据的一致性,因此是唯一推荐在遍历时修改集合的方式。

在实际开发中,必须使用迭代器的remove()或removeIf来保证代码的健壮性和可维护性。

结语

今天,我们算是开始了一个Java新板块的学习。

我们了解了Java集合框架是什么、它的宏观架构,了解了根接口Collection所定义的通用能力。

然后聊了一下迭代器和ConcurrentModificationException。

接下来我们会看一下集合框架下的一些具体实现。

下一篇预告

Day27 | List接口详解

如果你觉得这系列文章对你有帮助,欢迎关注专栏,我们一起坚持下去!

更多文章请关注我的公众号《懒惰蜗牛工坊》

相关推荐
电摇小人13 分钟前
我的“C++之旅”(博客之星主题作文)
java·开发语言
资生算法程序员_畅想家_剑魔14 分钟前
Java常见技术分享-23-多线程安全-总结
java·开发语言
萧曵 丶30 分钟前
ArrayList 和 HashMap 自动扩容机制详解
java·开发语言·面试
这是程序猿1 小时前
基于java的ssm框架学生作业管理系统
java·开发语言·spring boot·spring·学生作业管理系统
千百元1 小时前
限制网段访问服务器端口63790
java·网络·mybatis
宋情写1 小时前
JavaAI03-数据来源
java
钦拆大仁1 小时前
JDK17新特性
java
小程故事多_801 小时前
Spring AI 赋能 Java,Spring Boot 快速落地 LLM 的企业级解决方案
java·人工智能·spring·架构·aigc
努力的小雨1 小时前
从“Agent 元年”到 AI IDE 元年——2025 我与 Vibe Coding 的那些事儿
后端·程序员
Caarlossss1 小时前
mybatis
java·数据库·tomcat·maven·mybatis·mybatis-spring