Collection 单列集合与 List 全家桶 🔥
数组长度固定、功能太少?遇到动态数据就头大?
学完
数组的定长限制后,Java 集合就是来解决这个问题的万能伸缩容器 🎒。今天我们先搞定Collection 接口 和 List 集合,小白也能一次学会!
一、Collection 单列集合「顶层老大」📦
idea 快捷键 :itit → 快速生成迭代器 while 循环
1.1 核心概念
Collection是所有单列集合的顶层接口 ,它定义了单列集合的共性行为。- JDK 不提供它的直接实现,而是通过更具体的子接口(List、Set)实现。
- 创建
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 特点
- 有序 ✅:存入顺序与取出顺序完全一致。
- 有索引 🔢:元素有位置编号,从0开始(与数组规则一致)。
- 可重复 🔄:同一元素可多次存入集合。
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
原因 :
迭代器遍历的时候,用集合对象增删元素。
解决方法:
- 使用迭代器自带的
remove() - 使用普通 for 循环遍历
- 使用
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");
}
}
本篇总结 📝
- Collection:单列集合顶层接口,定义了增删查改等共性方法 📦
- List:有序、有索引、可重复,主要实现类有 ArrayList 和 LinkedList 📋
- 遍历方式:迭代器、增强 for、普通 for(仅 List)🔄
- 坑点:并发修改异常,迭代时别用集合增删 ⚠️
- ArrayList vs LinkedList :
- ArrayList:数组实现,查改快,增删慢 🔍
- LinkedList:链表实现,增删快,查询慢 ⚡
🚀 下一篇预告:《三十三、Java集合(二)------Set集合与Collections工具类》------ 搞定 HashSet、TreeSet 去重排序,还有 Collections 工具类一把梭!
作者 :书源丶
发布平台 :CSDN
系列:「Java基础篇」