哈喽各位Java打工人~👨💻 初学Java时,是不是刚摸熟数组就被老师塞了“集合”这个新玩意?心里直犯嘀咕:数组好好的,为啥非要整集合?今天咱就掰开揉碎了聊——从数组的“致命痛点”到Collection体系的“真香定律”,保证通俗易懂还不枯燥!

一、先吐槽:数组的那些“坑”,谁用谁知道

先看一段熟悉的代码:

// 定义一个长度为10的学生数组 Student[] arr = new Student[10]; // 想往第11个位置塞元素?直接报错! arr[11] = new Student(); // ArrayIndexOutOfBoundsException // 想删个元素?抱歉,数组压根没这方法 arr.remove(); // 编译报错! // 想插个元素?自己手动挪位置吧… arr.add(); // 同样编译报错!

总结数组的3大“硬伤”:

  1. 长度焊死:一旦创建,长度改不了,多插一个就报错,少用一堆还浪费空间;

  2. 增删巨麻烦:没有现成的add/remove方法,想删元素得手动遍历、挪位置,代码写得头皮麻;

  3. 功能太单薄:想判断有没有某个元素?想知道存了多少个?全得自己写逻辑。

这时候,集合(Collection) 就像救星一样出现了——专治数组的各种不服!

二、集合的“家族族谱”:Collection体系结构

集合不是单个类,而是一个“大家族”,咱们先看核心的单列集合体系(Map是双列集合,今天先挖个坑,下篇聊~):

    Collection接口:单列集合的顶级接口
        |--List接口:有序
            |--ArrayList类:底层是动态数组,set和get速度快,add和remove速度慢因为要移动数据
            |--Vector类:线程安全的ArrayList
            |--LinkedList类:底层是双向链表,add和remove速度快,set和get速度慢因为没有下标
    Map:
        |--
        |--

给大家打个比方:

  • Collection是“家族总掌门”,定义了单列集合的通用规矩;

  • List是“嫡系分支”,主打“有序”(存进去啥顺序,取出来还是啥顺序)、“可重复”;

    • ArrayList:家里有“动态数组”家底,查数据(get/set)贼快,但增删要挪数据,慢一点;

    • Vector:ArrayList的“老大哥”,线程安全但效率低,现在基本被淘汰;

    • LinkedList:家里靠“双向链表”吃饭,增删元素只改指针,贼快,但查数据要从头找,慢一点;

  • Map:另一个“旁支大佬”(双列集合,键值对存储),比如HashMap、Hashtable,咱下篇详聊~

三、核心基础:Collection接口(所有单列集合的“通用规矩”)

1. 它是啥?

Collection是所有单列集合的顶级接口,不管是ArrayList还是LinkedList,都得遵守它定的规矩——比如添加、删除、判断是否为空等。

2. 必掌握的核心方法(直接能用,真香!)

方法

作用

boolean add(E e)

往集合里加元素,成功返回true

boolean remove(Object o)

删除指定元素,存在则删并返回true

int size()

返回集合里元素的个数(终于不用自己数了!)

boolean isEmpty()

判断集合是不是空的

boolean contains(Object obj)

判断集合里有没有指定元素

Iterator iterator()

返回迭代器,用来遍历集合

代码示例:

import java.util.ArrayList; import java.util.Collection; public class CollectionDemo { public static void main(String[] args) { // 用ArrayList实现Collection接口(多态) Collection<String> coll = new ArrayList<>(); // 1. 添加元素 coll.add("张三"); coll.add("李四"); coll.add("王五"); System.out.println("添加后:" + coll); // [张三, 李四, 王五] // 2. 删除元素 coll.remove("李四"); System.out.println("删除李四后:" + coll); // [张三, 王五] // 3. 获取元素个数 System.out.println("元素个数:" + coll.size()); // 2 // 4. 判断是否为空 System.out.println("是否为空:" + coll.isEmpty()); // false // 5. 判断是否包含某个元素 System.out.println("是否包含张三:" + coll.contains("张三")); // true } }

四、List接口:Collection的“亲儿子”,主打一个“有序”

1. 它是啥?

List是Collection的子接口,最大特点:元素存取有序、可重复,而且每个元素都有自己的“下标”(和数组一样),这也是它和Set最核心的区别。

2. List特有的“专属方法”(比Collection多的狠活)

因为List有下标,所以多了一堆“按下标操作”的方法,直接拿捏数组的优点,还弥补了缺点:

方法

作用

void add(int index,E element)

往指定下标插元素,其他元素自动后移

E get(int index)

按下标取元素(数组的优点保留了!)

E set(int index,E element)

修改指定下标的元素

E remove(int index)

删除指定下标的元素

代码示例:

import java.util.ArrayList; import java.util.List; public class ListDemo { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Java"); list.add("Python"); // 1. 往下标1的位置插元素 list.add(1, "C++"); System.out.println("插入后:" + list); // [Java, C++, Python] // 2. 按下标取元素 String s = list.get(1); System.out.println("下标1的元素:" + s); // C++ // 3. 修改下标2的元素 list.set(2, "Go"); System.out.println("修改后:" + list); // [Java, C++, Go] // 4. 删除下标0的元素 list.remove(0); System.out.println("删除后:" + list); // [C++, Go] } }

五、ArrayList、Vector、LinkedList:三兄弟怎么选?

光知道理论不够,咱得知道啥场景用啥!用表格总结最清晰:

类名

底层实现

核心特点

适用场景

ArrayList

动态数组

查询快(get/set)、增删慢

读多写少(比如查商品列表)

Vector

动态数组

线程安全、效率极低

几乎不用(被CopyOnWriteArrayList替代)

LinkedList

双向链表

增删快(add/remove)、查询慢

写多读少(比如消息队列、频繁插删)

💡 小技巧:日常开发优先用ArrayList,除非明确需要频繁增删,再换LinkedList;Vector直接忽略就好~

总结

  1. 集合的出现是为了解决数组长度固定、增删麻烦、功能单薄的痛点;

  2. Collection是单列集合的顶级接口,定义了add/remove/size等通用方法;

  3. List接口继承Collection,主打有序、可重复,新增了按下标操作的方法;

  4. ArrayList(查快删慢)、LinkedList(删快查慢)是List的核心实现,Vector几乎不用。

看完是不是觉得集合一点都不抽象了?😜 收藏起来慢慢看,下篇咱们聊Map家族(HashMap/Hashtable这些),关注不迷路~

如果觉得有用,记得点赞+收藏哦!有问题评论区聊~👇

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐