Collectors类,是JDK1.8开始提供的一个的工具类,它专门用于对Stream操作流中的元素各种处理操作,Collectors类中提供了一些常用的方法,例如:toList()、toSet()、toCollection()、toMap()、toConcurrentMap()方法,以及一些分组聚合的方法。
Stream操作流
注意:Collectors类中的方法都是需要和Stream类中的collect()方法结合使用的。
toList、toSet方法是将Stream流中的数据,提取出来,转换成集合返回。
public static List<User> getUserList() {
List<User> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(new User(i+11, "name_00" + i, "test_0" + i));
}
return list;
}
public static void main(String[] args) {
List<User> userList = getUserList();
// 转换 List 集合
List<String> list = userList.stream().map(User::getUname).collect(Collectors.toList());
System.out.println(list);
// 转换 Set 集合
Set<String> list2 = userList.stream().map(User::getPassword).collect(Collectors.toSet());
System.out.println(list2);
}
toMap、toConcurrentMap两个方法的作用是一样的,只不过toConcurrentMap方法是线程安全的。这两个方法在使用的时候,至少需要传递两个参数,分别是:
public static void main(String[] args) {
List<User> userList = getUserList();
// 转换为map集合
Map<Integer, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, item -> item, (x, y) -> {
if (Objects.equals(x.getId(), y.getId())) {
System.out.println("key发生重复啦");
return x;
}
return y;
}));
System.out.println(userMap);
}
joining方法的作用就是将Stream流中的元素按照指定的格式拼接起来,该方法有哪个重载类型,分别如下所示:
public static void main(String[] args) {
List<User> userList = getUserList();
// joining 连接
String join1 = userList.stream().map(User::getUname).collect(Collectors.joining());
String join2 = userList.stream().map(User::getUname).collect(Collectors.joining(","));
String join3 = userList.stream().map(User::getUname).collect(Collectors.joining(",", "[", "]"));
System.out.println(join1);
System.out.println(join2);
System.out.println(join3);
}
counting方法用于统计元素个数,一般不会单独使用,会和groupingBy结合使用。
// counting 统计
Long count = userList.stream().collect(Collectors.counting());
System.out.println(count);
groupingBy方法用于将Stream流中的元素,按照某个分组规则将其分组。groupingBy方法返回值是一个Map集合,集合中的key表示分组的唯一标识,value则表示分组后的所有元素,默认是List集合。
groupingBy方法有多个参数的重载,如下所示:
案例代码如下:
public static void main(String[] args) {
List<User> userList = new ArrayList<>();
userList.add(new User(1001, "java", "123"));
userList.add(new User(1002, "html", "123"));
userList.add(new User(1003, "css", "123"));
userList.add(new User(1004, "js", "123"));
userList.add(new User(1005, "java", "123"));
userList.add(new User(1006, "css", "123"));
// 按照 name 分组
Map<String, List<User>> map = userList.stream().collect(Collectors.groupingBy(User::getUname));
System.out.println(map);
// 按照 name 分组,并且计算每一组中 id 平均值
Map<String, Double> map1 = userList.stream().collect(Collectors.groupingBy(User::getUname, Collectors.averagingDouble(User::getId)));
System.out.println(map1);
}
partitioningBy方法是分区的,它是一种特殊的分组groupingBy,前面介绍了groupingBy是将数组按照某个key分组成多个集合,最终得到一个Map
而这里的partitioningBy意味分区,它是将数据分为两组,一组是满足条件的分区,另外一组则是不满足条件的分组,最终返回的结果是一个Map
public static void main(String[] args) {
// 分区
Integer[] nums = new Integer[] { 1, 2, 3, 4, 5 };
// 将大于 3 的作为一组
Map<Boolean, List<Integer>> map = Arrays.stream(nums).collect(Collectors.partitioningBy(item -> item > 3));
System.out.println(map);
}
运行结果如下所示: