单列集合Collection接口
Collection接口
- Collection 是 Java 集合框架中的一个核心接口,位于 java.util 包中。它是所有单列集合(即存储单个元素的集合)的根接口,提供了对集合进行基本操作的方法。
定义的通用方法
-
添加元素
-
boolean add(E e)向集合中添加一个元素,元素成功添加返回 true,反之返回false
Collection<String> collection = new ArrayList<>(); collection.add("Apple"); // 返回 true collection.add("Apple"); // 如果集合不允许重复元素,返回 false -
boolean addAll(Collection<? extends E> c),将指定集合中的所有元素添加到当前集合中,如果当前集合因调用此方法而发生变化 true,如果指定集合为空或所有元素都已存在于当前集合中返回false
Collection<String> collection1 = new ArrayList<>(); collection1.add("Apple"); collection1.add("Banana"); Collection<String> collection2 = new ArrayList<>(); collection2.add("Cherry"); collection2.add("Banana"); collection1.addAll(collection2); // 返回 true,collection1 现在包含 ["Apple", "Banana", "Cherry"]
-
-
删除元素
-
boolean remove(Object o)从集合中移除指定的元素,如果集合包含该元素并成功移除,返回 true,如果集合不包含该元素,返回 false
Collection<String> collection = new ArrayList<>(); collection.add("Apple"); collection.add("Banana"); collection.remove("Apple"); // 返回 true collection.remove("Cherry"); // 返回 false -
boolean removeAll(Collection<?> c)从当前集合中移除所有包含在指定集合中的元素,如果当前集合因调用此方法而发生变化,返回 true,如果当前集合未发生变化,返回 false
Collection<String> collection1 = new ArrayList<>(); collection1.add("Apple"); collection1.add("Banana"); collection1.add("Cherry"); Collection<String> collection2 = new ArrayList<>(); collection2.add("Apple"); collection2.add("Cherry"); collection1.removeAll(collection2); // 返回 true,collection1 现在只包含 ["Banana"] -
boolean retainAll(Collection<?> c)仅保留当前集合中那些也包含在指定集合中的元素(即求交集),变化为true,反之为false
Collection<String> collection1 = new ArrayList<>(); collection1.add("Apple"); collection1.add("Banana"); collection1.add("Cherry"); Collection<String> collection2 = new ArrayList<>(); collection2.add("Apple"); collection2.add("Cherry"); collection1.retainAll(collection2); // 返回 true,collection1 现在只包含 ["Apple", "Cherry"] -
void clear()移除集合中的所有元素,清空集合
Collection<String> collection = new ArrayList<>(); collection.add("Apple"); collection.add("Banana"); collection.clear(); // 清空集合,collection 现在为空
-
-
查询操作
-
boolean contains(Object o)判断集合中是否包含指定的元素,如果集合包含该元素,返回 true
Collection<String> collection = new ArrayList<>(); collection.add("Apple"); System.out.println(collection.contains("Apple")); // 输出 true System.out.println(collection.contains("Banana")); // 输出 false -
boolean containsAll(Collection<?> c)判断集合中是否包含指定集合中的所有元素,如果集合包含指定集合中的所有元素,返回 true
Collection<String> collection1 = new ArrayList<>(); collection1.add("Apple"); collection1.add("Banana"); Collection<String> collection2 = new ArrayList<>(); collection2.add("Apple"); System.out.println(collection1.containsAll(collection2)); // 输出 true -
boolean isEmpty()判断集合是否为空,如果集合中没有元素,返回 true
Collection<String> collection = new ArrayList<>(); System.out.println(collection.isEmpty()); // 输出 true collection.add("Apple"); System.out.println(collection.isEmpty()); // 输出 false -
int size()返回集合中的元素数量
Collection<String> collection = new ArrayList<>(); collection.add("Apple"); collection.add("Banana"); System.out.println(collection.size()); // 输出 2
-
-
集合转换
-
Object[] toArray()将集合转换为一个数组,数组中的元素是集合中的所有元素
Collection<String> collection = new ArrayList<>(); collection.add("Apple"); collection.add("Banana"); Object[] array = collection.toArray(); System.out.println(Arrays.toString(array)); // 输出 [Apple, Banana]
-
迭代器
-
iterator() 是 Collection 接口中的一个重要方法,用于返回一个 迭代器(Iterator) 对象。迭代器是 Java 集合框架中用于遍历集合元素的工具,它提供了一种统一的方式来访问集合中的元素,而不需要关心集合的具体实现
-
iterator() 方法返回的是一个实现了 Iterator 接口的对象。Iterator 接口定义了以下三个核心方法
-
boolean hasNext():判断集合中是否还有下一个元素,如果集合中还有未遍历的元素,返回 true
-
E next():返回集合中的下一个元素,并将迭代器的指针向后移动一位返回值:集合中的下一个元素
- 如果集合中没有更多元素(即 hasNext() 返回 false),调用 next() 会抛出 NoSuchElementException
-
void remove():从集合中移除迭代器最后一次返回的元素(即最近一次调用 next() 返回的元素)
- 每次调用 next() 后只能调用一次 remove(),否则会抛出 IllegalStateException
- 如果集合不支持移除操作,调用 remove() 会抛出 UnsupportedOperationException
-
Iterator 的工作机制
-
迭代器内部维护一个指针(或游标),初始时指向集合的第一个元素之前的位置。
-
每次调用 next(),指针会向后移动一位,并返回当前指向的元素。
-
hasNext() 用于判断指针是否已经到达集合的末尾。
-
remove() 会移除最后一次 next() 返回的元素
使用 Iterator 遍历集合的步骤
-
调用集合的 iterator() 方法获取迭代器对象。
-
使用 hasNext() 检查是否还有元素。
-
使用 next() 获取下一个元素。
-
(可选)使用 remove() 移除元素
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorExample {
public static void main(String[] args) {
// 创建一个 ArrayList 集合
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
list.add("Date");
// 获取迭代器
Iterator<String> iterator = list.iterator();
// 遍历集合
System.out.println("遍历集合:");
while (iterator.hasNext()) {
String item = iterator.next(); // 获取下一个元素
System.out.println("当前元素:" + item);
// 如果元素是 "Banana",则移除
if (item.equals("Banana")) {
iterator.remove(); // 移除最后一次 next() 返回的元素
System.out.println("已移除元素:Banana");
}
}
// 输出修改后的集合
System.out.println("\n修改后的集合:");
for (String item : list) {
System.out.println(item);
}
}
}
迭代器的优点
-
通用性:Iterator 可以用于遍历任何实现了 Collection 接口的集合类(如 ArrayList、HashSet、LinkedList 等)。
-
安全性:在遍历过程中,如果集合被修改(非通过迭代器自身的 remove() 方法),迭代器会抛出 ConcurrentModificationException,从而避免数据不一致的问题。
-
灵活性:Iterator 提供了 remove() 方法,可以在遍历时安全地移除元素
迭代器的注意点
-
单向遍历:Iterator 只能向前遍历,不能后退。
-
一次性使用:一个迭代器对象只能遍历集合一次。如果需要重新遍历,必须重新获取迭代器。
-
并发修改:在遍历过程中,如果直接通过集合的方法(如 add()、remove())修改集合,会抛出 ConcurrentModificationException。如果需要修改集合,应使用迭代器的 remove() 方法。
增强for循环
-
增强 for 循环(for-each 循环)是 Java 5 引入的语法糖,底层实际使用的是 Iterator
for (String item : collection) { System.out.println(item); } //等价于 Iterator<String> iterator = collection.iterator(); while (iterator.hasNext()) { String item = iterator.next(); System.out.println(item); }
迭代器的并发修改问题
-
在 Java 集合框架中,许多集合类(如 ArrayList、HashSet 等)都是 非线程安全 的。这些集合类内部维护了一个 修改计数器(modCount),用于记录集合被修改的次数(如添加、删除元素)
-
当使用 Iterator 遍历集合时,迭代器会在初始化时记录当前的 modCount 值。在遍历过程中,每次调用迭代器的 next() 或 remove() 时,迭代器会检查集合的 modCount 是否与初始化时记录的 modCount 一致。如果不一致,说明集合在遍历过程中被外部修改(非通过迭代器自身的方法),此时迭代器会抛出 ConcurrentModificationException
-
ConcurrentModificationException 是一种 快速失败(fail-fast) 机制,旨在提醒开发者集合在遍历过程中被意外修改,可能导致数据不一致或不可预期的行为
-
只有添加和删除操作会触发 ConcurrentModificationException,而修改操作(如 list.set())通常不会触发该异常
-
ConcurrentModificationException 的触发条件是 结构性修改(structural modification),即改变集合的大小(如添加或删除元素)
-
list.set() 只是修改了集合中某个元素的值,并没有改变集合的大小,因此不会触发 ConcurrentModificationException
List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); list.add("D"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (item.equals("B")) { // 直接通过集合的 remove() 方法修改集合 //这里需要注意如果list的集合没有添加字符D则不会报错,因为iterator.hasNext()为false会结束程序而不会进行检测 //如果list的集合添加了字符D,则会执行到next()方法进行检测,则报错 list.remove(item); } }-
使用 Iterator 遍历 ArrayList。
-
当遍历到元素 "B" 时,直接调用 list.remove(item) 修改集合。
-
由于集合的 modCount 发生了变化,而迭代器记录的 modCount 未更新,因此在下一次调用 iterator.next() 时,会抛出 ConcurrentModificationException
-
-
快速失败机制主要是为了检测在迭代过程中对 集合 结构的修改(如添加或删除值),而不是对已有值的修改,因为没有改动修改计数器(modCount)
List<Person> list = new ArrayList<>(); list.add(new Person(1)); list.add(new Person(2)); list.add(new Person(3)); Iterator<Person> iterator = list.iterator(); while (iterator.hasNext()) { Person item = iterator.next(); if (item.id==2) { item.setId(20); // 可以修改已有值 } } -
为了避免 ConcurrentModificationException,在遍历集合时,如果需要修改集合,应使用迭代器自身的 remove() 方法,而不是直接通过集合的方法修改
List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String item = iterator.next(); if (item.equals("B")) { iterator.remove(); // 使用迭代器的 remove() 方法 } }- 每次调用 next() 后只能调用一次 remove():如果在调用 remove() 之前没有调用 next(),或者多次调用 remove(),会抛出 IllegalStateException
- 不支持添加操作:Iterator 只提供了 remove() 方法,不支持添加元素。如果需要添加元素,可以考虑使用 ListIterator(它是 Iterator 的子接口,支持添加和修改操作)
-
如果需要在遍历过程中频繁修改集合,可以考虑以下替代方案
-
使用 ListIterator,ListIterator 是 Iterator 的增强版,支持在遍历过程中添加、修改和删除元素
注意Collection 接口中只提供了 Iterator,ListIterator 是 List 特有的功能,适用于有序集合
List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); ListIterator<String> listIterator = list.listIterator(); while (listIterator.hasNext()) { String item = listIterator.next(); if (item.equals("B")) { listIterator.remove(); // 删除元素 listIterator.add("D"); // 添加元素 } } -
使用 CopyOnWriteArrayList
-
CopyOnWriteArrayList 是线程安全的集合类,它在修改集合时会创建一个新的副本,因此不会抛出 ConcurrentModificationException
-
List<String> list = new CopyOnWriteArrayList<>(); list.add("A"); list.add("B"); list.add("C"); for (String item : list) { if (item.equals("B")) { list.remove(item); // 直接修改集合 } }
-
-
使用普通 for 循环,如果需要通过索引修改集合,可以使用普通 for 循环
List<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); for (int i = 0; i < list.size(); i++) { String item = list.get(i); if (item.equals("B")) { list.remove(i); // 直接通过索引修改集合 i--; // 调整索引 } }
-
方法总结
Collection 接口提供了对集合进行添加、删除、查询、遍历和转换的通用方法。这些方法是所有单列集合类的基础,适用于 List、Set、Queue 等集合类型。
1. 添加元素
add(E e):向集合中添加一个元素。成功添加返回 true,否则返回 false。addAll(Collection<? extends E> c):将指定集合中的所有元素添加到当前集合中。集合发生变化返回 true,否则返回 false。
2. 删除元素
remove(Object o):移除集合中的指定元素。成功移除返回 true,否则返回 false。removeAll(Collection<?> c):移除当前集合中所有包含在指定集合中的元素。集合发生变化返回 true,否则返回 false。retainAll(Collection<?> c):仅保留当前集合中那些也包含在指定集合中的元素(求交集)。集合发生变化返回 true,否则返回 false。clear():清空集合中的所有元素。
3. 查询操作
contains(Object o):判断集合是否包含指定元素。包含返回 true,否则返回 false。containsAll(Collection<?> c):判断集合是否包含指定集合中的所有元素。包含返回 true,否则返回 false。isEmpty():判断集合是否为空。为空返回 true,否则返回 false。size():返回集合中的元素数量。
4. 集合转换
toArray():将集合转换为一个 Object 数组。toArray(T[] a):将集合转换为指定类型的数组。
5. 遍历集合
iterator():返回一个用于遍历集合中元素的迭代器。

浙公网安备 33010602011771号