在Java中,集合框架提供了一组标准化的接口和类,用于处理一组对象。集合框架中的一个核心接口是 Collection
,它定义了单列集合的通用操作。单列集合(也称为线性集合)是指存储一组对象的集合,如列表、集合和队列。本文将深入探讨 Collection
接口,涵盖其定义、常用方法、实现类及其实际应用。
1. 什么是Collection接口?
Collection
接口是Java集合框架中的顶层接口之一,定义了单列集合的基本操作。它是一个通用的接口,广泛用于表示一组对象的集合。Collection
接口本身不能直接实例化,因为它是一个接口而不是类,但我们可以使用它的各种实现类,如 ArrayList
、HashSet
、LinkedList
等。
2. Collection接口的常用方法
- boolean add(E e) 添加元素到集合中。
- void clear() 清空集合。
- boolean remove(Object o) 从集合中删除指定的元素。
- boolean contains(Object o) 判断集合是否包含指定的元素。
- boolean isEmpty() 判断集合是否为空。
- int size() 获取集合的大小。
3. Collection接口的实现类
Collection
接口有许多实现类,这些实现类根据不同的数据存储结构和访问方法提供了各种集合类型。以下是一些常用的实现类及其特点:
3.1 List接口及其实现类
List
接口继承自 Collection
接口,表示一个有序的元素集合。元素可以重复,且有索引。常见的实现类有:
ArrayList
: 基于动态数组的实现,访问元素速度快,但在中间插入或删除元素时速度较慢。LinkedList
: 基于链表的实现,适合频繁插入和删除的场景,但访问速度较慢。Vector
: 线程安全的动态数组实现,性能较低,已不推荐使用。
3.2 Set接口及其实现类
Set
接口继承自 Collection
接口,表示一个无序、无重复元素、无索引的集合。常见的实现类有:
HashSet
: 基于哈希表的实现,元素无序,插入、删除和查找操作的时间复杂度为O(1)。LinkedHashSet
: 继承自HashSet
,但维护了元素的插入顺序。TreeSet
: 基于红黑树的实现,元素有序(自然排序或定制排序)。
3.3 Queue接口及其实现类
Queue
接口继承自 Collection
接口,表示一个先进先出(FIFO)的集合。常见的实现类有:
LinkedList
: 可以用作队列的双向链表实现。PriorityQueue
: 基于优先级堆的实现,元素按自然排序或定制排序进行优先级排列。
4. 使用 ArrayList 实现 Collection 接口
`ArrayList` 是一个常用的集合类,它实现了 `List` 接口,允许元素重复。我们可以使用 `ArrayList` 来存储和操作元素。下面是一些基本操作的示例:
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
// 添加元素
//细节1:如果我们要往List系列集合中添加数据,那么方法永远返回true,因为List系列的是允许元素重复的。
//细节2:如果我们要往Set系列集合中添加数据,如果当前要添加元素不存在,方法返回true,表示添加成功。
// 如果当前要添加的元素已经存在,方法返回false,表示添加失败。
// 因为Set系列的集合不允许重复。
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
System.out.println(coll); // 输出: [aaa, bbb, ccc]
// 删除元素
System.out.println(coll.remove("aaa")); // 输出: true
System.out.println(coll); // 输出: [bbb, ccc]
// 判断是否包含元素
//细节:底层是依赖equals方法进行判断是否存在的。
//所以,如果集合中存储的是自定义对象,也想通过contains方法来判断是否包含,那么在javabean类中,一定要重写equals方法。
//如果没有重写equals方法,那么默认使用Object类中的equals方法进行判断,而Object类中equals方法,依赖地址值进行判断。
boolean result1 = coll.contains("bbb");
System.out.println(result1); // 输出: true
// 判断集合是否为空
boolean result2 = coll.isEmpty();
System.out.println(result2); // 输出: false
// 获取集合的大小
coll.add("ddd");
int size = coll.size();
System.out.println(size); // 输出: 3
}
}
在上述代码中,我们展示了如何创建一个 `ArrayList` 集合,并执行添加、删除、判断是否包含元素、判断是否为空以及获取集合大小等操作。
5. 集合的三种通用遍历方式
5.1 迭代器遍历
迭代器提供了一种统一的方式来遍历集合中的元素。通过调用 `iterator()` 方法,我们可以获得一个 `Iterator` 对象,然后使用 `hasNext()` 和 `next()` 方法来遍历集合。
迭代器遍历相关的三个方法:
Iterator<E> iterator() :获取一个迭代器对象
boolean hasNext() :判断当前指向的位置是否有元素
E next() :获取当前指向的元素并移动指针
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class IteratorDemo {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
Iterator<String> it = coll.iterator();
while (it.hasNext()) {
String str = it.next();
System.out.println(str);
}
}
}
注意:
迭代器的细节注意点:
1.如果当前位置没有元素,还要强行获取,报错NoSuchElementException
2.迭代器遍历完毕,指针不会复位
3.循环中只能用一次next方法
4.迭代器遍历时,不能用集合的方法进行增加或者删除,需要使用迭代器提供的remove方法
暂时当做一个结论先行记忆,在今天我们会讲解源码详细的再来分析。
如果我实在要删除:那么可以用迭代器提供的remove方法进行删除。 如果我要添加,暂时没有办法。
5.2 增强 for 循环
增强 `for` 循环(也称为 `foreach` 循环)是对迭代器的一种简化。它的语法更简洁,适合对集合或数组进行遍历。底层就是一个迭代器遍历。
增强for格式:
for(数据类型 变量名: 集合/数组){
}
import java.util.ArrayList;
import java.util.Collection;
public class ForEachDemo {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("zhangsan");
coll.add("lisi");
coll.add("wangwu");
for (String s : coll) {
System.out.println(s);
}
}
}
5.3 Lambda 表达式
Lambda 表达式是 Java 8 引入的新特性,它使得遍历集合变得更加简洁。forEach 方法接受一个 Consumer 接口的实例,Lambda 表达式可以用来简化这个过程。
lambda表达式遍历:
default void forEach(Consumer<? super T> action):
import java.util.ArrayList;
import java.util.Collection;
public class LambdaDemo {
public static void main(String[] args) {
Collection<String> coll = new ArrayList<>();
coll.add("zhangsan");
coll.add("lisi");
coll.add("wangwu");
coll.forEach(s -> System.out.println(s));
}
}
6.总结
Lambda 表达式没有学明白!