Collection, Collections, 和 Collectors 是 Java 集合框架中三个容易混淆但功能完全不同的概念。它们分别代表了接口、工具类和收集器工具类。
Collection 是一个接口,位于 java.util 包中,定义了单列集合的各种行为规范; Collections 是一个工具类,位于 java.util 包中,提供了许多静态方法来操作或返回集合,以辅助集合的操作。Collectors 是 Java 8 引入的一个收集器工具类,位于 java.util.stream 包中。它提供了用于 Stream.collect() 方法的各种 Collector 实现。
- Collection:
-
Collection是一个接口,它是所有集合类的根接口。它定义了集合的基本操作,如添加元素、删除元素、遍历元素等。 -
实现
Collection接口的具体类包括ArrayList,LinkedList,HashSet,TreeSet等。这些类提供了对集合的不同实现方式,比如基于数组的实现(ArrayList)、链表实现(LinkedList)、哈希表实现(HashSet)和树形结构实现(TreeSet)。例:
Collection接口的ArrayList类:
import java.util.ArrayList;
import java.util.Collection;
public class CollectionExample {
public static void main(String[] args) {
// 创建一个ArrayList实例,它是Collection的一个实现
Collection<String> collection = new ArrayList<>();
// 添加元素到集合中
collection.add("Apple");
collection.add("Banana");
collection.add("Orange");
// 遍历并打印集合中的元素
for (String element : collection) {
System.out.println(element);
}
// 检查集合是否包含特定元素
boolean hasBanana = collection.contains("Banana");
System.out.println("Contains Banana: " + hasBanana);
// 删除集合中的元素
collection.remove("Banana");
// 打印删除后的集合大小
System.out.println("Size after removal: " + collection.size());
}
}
- Collections:
-
Collections是一个工具类,提供了一系列静态方法,帮助我们操作或返回集合。它包含各种实用的方法来处理或操作Collection或其子类型的对象,例如排序、混排、同步控制等。 -
例如,
Collections.sort()方法可以用来对实现了List接口的对象进行排序;Collections.synchronizedList()方法可以返回指定列表支持的同步(线程安全)列表。 -
这个类不能被实例化,因为它只包含静态方法和静态变量。
例:
import java.util.*;
public class CollectionsExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Orange");
list.add("Apple");
list.add("Banana");
// 使用Collections.sort()方法对列表进行排序
Collections.sort(list);
System.out.println("Sorted list: " + list);
// 使用Collections.shuffle()方法随机排列列表元素
Collections.shuffle(list);
System.out.println("Shuffled list: " + list);
// 使用Collections.synchronizedList()方法创建线程安全的列表
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
syncList.add("ThreadSafeItem");
System.out.println("Synchronized list content: " + syncList);
// 使用Collections.unmodifiableList()方法创建只读列表
List<String> unmodifiableList = Collections.unmodifiableList(list);
// 下面这行代码会抛出UnsupportedOperationException异常,因为unmodifiableList是只读的
// unmodifiableList.add("New Item");
}
}
Collections的常用方法
- **`Collections.singletonList(T item)`** : 创建一个只包含指定元素的、不可变的 `List`。
- **`Collections.emptyList()`** : 返回一个空的、不可变的 `List`。
3. Collectors:
- Collectors 类是 Java 8 引入的 java.util.stream.Collectors 工具类,它提供了各种用于 Stream.collect() 方法的收集器(Collector),这些收集器允许你对流中的元素进行累积、分组、分区等操作。通过 Collectors 提供的方法,你可以方便地将流转换成不同的集合类型,或者执行复杂的聚合操作。
特点:
- 灵活性:
Collectors提供了非常灵活的方式来处理流数据,无论是简单的收集到集合,还是复杂的分组、分区操作。 - 高效性:使用
Collectors可以有效地利用流式处理的优势,尤其是对于大数据集时,能够显著提升性能。 - 易用性:通过静态导入
Collectors的方法,可以简化代码,使其更加简洁易读。
以下是 Collectors 类中一些常用的方法:
基本收集
-
toList():将流中的元素收集到一个
List中。List<String> list = stream.collect(Collectors.toList()); -
toSet():将流中的元素收集到一个
Set中,自动去除重复项。
Set<String> set = stream.collect(Collectors.toSet());
- toCollection(Supplier<Collection> collectionFactory):使用指定的集合工厂函数创建集合,并将流中的元素收集到这个集合中。
Collection<String> collection = stream.collect(Collectors.toCollection(ArrayList::new));
- toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper):将流中的元素收集到一个
Map中,需要提供键值映射的函数。
Map<Integer, String> map = stream.collect(Collectors.toMap(Person::getId, Person::getName));
聚合操作
- joining() / joining(CharSequence delimiter) / joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix):连接字符串流中的所有元素。可以指定分隔符,前缀和后缀。
String joined = stream.collect(Collectors.joining(","));
- counting():返回流中元素数量的总数。
Long count = stream.collect(Collectors.counting());
分组与分区
- groupingBy(Function<? super T,? extends K> classifier):根据提供的分类函数对流中的元素进行分组,返回一个
Map<K, List<T>>。
Map<Integer, List<Person>> groupedByAge = people.stream().collect(Collectors.groupingBy(Person::getAge));
- partitioningBy(Predicate<? super T> predicate):根据提供的谓词对流中的元素进行分区(true/false),返回一个
Map<Boolean, List<T>>。
Map<Boolean, List<Person>> partitioned = people.stream().collect(Collectors.partitioningBy(person -> person.getAge() > 18));
组合使用
-
mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream)
在收集之前对每个输入元素应用映射函数。
List<String> names = people.stream().collect(Collectors.mapping(Person::getName, Collectors.toList())); -
collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher):首先是收集,然后是对收集结果的转换(包装另一个收集器,对其结果应用一个完成器函数)。
Set<String> distinctNames = people.stream().collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));
// 找到年龄最大的人的名字
Optional<String> oldestPersonName = people.stream()
.collect(Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparing(Person::getAge)), // 下游收集器:找到年龄最大的 Person
maxPerson -> maxPerson.map(Person::getName) // 完成器函数:将 Optional<Person> 转换为 Optional<String>
));