简介
通过使用收集器,可以让代码更加方便的进行简化与重用。其内部主要核心是通过Collectors完成更加复杂的计算转换,从而获取到最终结果。并且Collectors内部提供了非常多的常用静态方法,直接拿来就可以了。比方说:toList
Collectors常用方法使用
通过counting()统计集合总数
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23));
studentList.add(new Student("李四", 20));
studentList.add(new Student("王五", 19));
studentList.add(new Student("小明", 21));
studentList.add(new Student("小红", 24));
Long collect = studentList.stream().collect(Collectors.counting());
System.out.println(collect);
//等同于
long count = studentList.stream().count();
System.out.println(count);
}
}
Collectors.counting 中内部做的调用reducing()进行数据汇总
public static <T> Collector<T, ?, Long> counting() {
return reducing(0L, e -> 1L, Long::sum);
}
通过maxBy()与minBy()获取最大值最小值
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23));
studentList.add(new Student("李四", 20));
studentList.add(new Student("王五", 19));
studentList.add(new Student("小明", 21));
studentList.add(new Student("小红", 24));
//获取年龄最大的学生
Optional<Student> max = studentList.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge)));
System.out.println(max);
//获取年龄最小的学生
Optional<Student> min = studentList.stream().collect(Collectors.minBy(Comparator.comparing(Student::getAge)));
System.out.println(min);
}
}
**
通过averagingInt()进行平均值获取
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23));
studentList.add(new Student("李四", 20));
studentList.add(new Student("王五", 19));
studentList.add(new Student("小明", 21));
studentList.add(new Student("小红", 24));
//法一:
Double collect = studentList.stream().collect(Collectors.averagingInt(Student::getAge));
System.out.println(collect);
//法二:提取年龄然后求平均值
OptionalDouble average = studentList.stream().mapToDouble(Student::getAge).average();
System.out.println(average);
}
}
**
通过summingInt()进行数据汇总
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23));
studentList.add(new Student("李四", 20));
studentList.add(new Student("王五", 19));
studentList.add(new Student("小明", 21));
studentList.add(new Student("小红", 24));
IntSummaryStatistics collect = studentList.stream().collect(Collectors.summarizingInt(Student::getAge));
//总数
System.out.println(collect.getCount());
//求和
System.out.println(collect.getSum());
//最小数
System.out.println(collect.getMin());
//平均数
System.out.println(collect.getAverage());
//最大数
System.out.println(collect.getMax());
}
}
**
通过joining()进行数据拼接
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23));
studentList.add(new Student("李四", 20));
studentList.add(new Student("王五", 19));
studentList.add(new Student("小明", 21));
studentList.add(new Student("小红", 24));
String collect = studentList.stream().map(Student::getName).collect(Collectors.joining(","));
System.out.println(collect);
}
}
内部通过StringBuilder来把每一个映射的值进行拼接
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
CharSequence prefix,
CharSequence suffix) {
return new CollectorImpl<>(
() -> new StringJoiner(delimiter, prefix, suffix),
StringJoiner::add, StringJoiner::merge,
StringJoiner::toString, CH_NOID);
}
分组
通过groupBy()实现对数据分组
**
简单分组
根据年龄分组学生信息
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23));
studentList.add(new Student("李四", 23));
studentList.add(new Student("王五", 19));
studentList.add(new Student("小明", 19));
studentList.add(new Student("小红", 20));
Map<Integer, List<Student>> collect = studentList.stream().collect(Collectors.groupingBy(Student::getAge));
System.out.println(collect);
}
}
**
结果:
{19=[Student{id=null, name='王五', age=19}, Student{id=null, name='小明', age=19}], 20=[Student{id=null, name='小红', age=20}], 23=[Student{id=null, name='张三', age=23}, Student{id=null, name='李四', age=23}]}
多级分组
Collectors.groupingBy提供了一个重载方法,其会在内层分组(第二个参数)结果,传递给外层分组(第一个参数)作为其继续分组的依据
按照年龄分组及是否及格分组
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23, true));
studentList.add(new Student("李四", 23, false));
studentList.add(new Student("王五", 19, true));
studentList.add(new Student("小明", 19, true));
studentList.add(new Student("小红", 20, true));
Map<Integer, Map<String, List<Student>>> collect = studentList.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(item -> {
if (item.isPass()) {
return "pass";
} else {
return "no pass";
}
})));
System.out.println(collect);
}
}
运行结果:
{19={pass=[Student{id=null, name='王五', age=19, pass=true}, Student{id=null, name='小明', age=19, pass=true}]}, 20={pass=[Student{id=null, name='小红', age=20, pass=true}]}, 23={pass=[Student{id=null, name='张三', age=23, pass=true}], no pass=[Student{id=null, name='李四', age=23, pass=false}]}}
多级分组变形
- 案例:根据年龄分组,然后统计总数
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23, true));
studentList.add(new Student("李四", 23, false));
studentList.add(new Student("王五", 19, true));
studentList.add(new Student("小明", 19, true));
studentList.add(new Student("小红", 20, true));
Map<Integer, Long> collect = studentList.stream().collect(Collectors.groupingBy(Student::getAge, Collectors.counting()));
System.out.println(collect);
}
}
运行结果:
{19=2, 20=1, 23=2}
- 案例:统计出每个年龄下,及格和未及格的人数
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23, true, 100));
studentList.add(new Student("李四", 23, false, 20));
studentList.add(new Student("王五", 19, true, 80));
studentList.add(new Student("小明", 19, false, 40));
studentList.add(new Student("小红", 19, true, 80));
Map<Integer, Map<Boolean, Long>> collect = studentList.stream().collect(Collectors.groupingBy(Student::getAge,
Collectors.groupingBy(Student::isPass,
Collectors.counting())));
System.out.println(collect);
}
}
案例:统计出每个年龄下,及格和未及格的最高分数
public class CollectorsDemo {
public static void main(String[] args) {
List<Student> studentList = new ArrayList<>();
studentList.add(new Student("张三", 23, true, 100));
studentList.add(new Student("李四", 23, false, 20));
studentList.add(new Student("王五", 19, true, 80));
studentList.add(new Student("小明", 19, false, 40));
studentList.add(new Student("小红", 19, true, 80));
Map<Integer, Map<Boolean, Student>> collect = studentList.stream().collect(Collectors.groupingBy(Student::getAge,
Collectors.groupingBy(Student::isPass,
Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparing(Student::getScope)), Optional::get))));
System.out.println(collect);
}
}
运行结果:
{19={false=Student{id=null, name='小明', age=19, pass=false}, true=Student{id=null, name='王五', age=19, pass=true}}, 23={false=Student{id=null, name='李四', age=23, pass=false}, true=Student{id=null, name='张三', age=23, pass=true}}}