目录
3.1.3 求和——Collectors.summingDouble
3.1.4 求平均值——Collectors.averagingDouble
3.1.5 统计数量——Collectors.counting()
3.2.1 简单的分组——Collectors.groupingBy
3.2.1 多级分组——Collectors.groupingBy
3.3 对流中的数据进行分区——Collectors.partitioningBy
3.4 对流中的数据进行拼接——Collertors.joining
1. 收集Stream流中的结果到集合
Stream流提供collect方法,其参数需要一个java.util.stream.Collector<T,A,R>接口对象来指定收集到哪种集合中。java.util.stream.Collectors类提供了一些方法,可以作为Collector接口的实例,最常用的就是静态方法toList与toSet
1.1 收集到List集合——toList
例如:
public static void testList(){
Stream<String> stream = Stream.of("张三", "李四", "王五", "赵六");
List<String> list = stream.collect(Collectors.toList());
System.out.println(list);
}
1.2 收集到Set集合——toSet
例如:
public static void testSet(){
Stream<String> stream = Stream.of("张三", "李四", "王五", "赵六");
Set<String> set = stream.collect(Collectors.toSet());
System.out.println(set);
}
1.3 收集到指定集合
例如:收集到ArrayList集合中
public static void testArrayList(){
Stream<String> stream = Stream.of("张三", "李四", "王五", "赵六");
ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
System.out.println(arrayList);
}
2. 收集集合中的数据到数组中
2.1 转成Object数组——toArray
例如:
public static void test2Array(){
Stream<String> stream = Stream.of("张三", "李四", "王五", "赵六");
Object[] array = stream.toArray();
for(Object o : array){
System.out.println(o);
}
}
该方式转成Object类型的数组,我们操作起来不是很方便
2.2 转成指定类型的数组——toArray
例如:将String流转成String数组
public static void test2Array1(){
Stream<String> stream = Stream.of("张三", "李四", "王五", "赵六");
String[] array = stream.toArray(String[]::new);
for(String str : array){
System.out.println("元素是:" + str + " 元素长度是:" + str.length());
}
}
3. 对流中的数据的操作
3.1 对流中的数据进行聚合计算
当我们使用Stream流处理数据后,可以像数据库聚合函数一样,对某个字段进行处理,比如,获取最大值,获取最小值,求总和,平均值,统计数量等。
3.1.1 获取最大值——Collectors.maxBy
例如:
public class StreamCollectTest01 {
public static void main(String[] args) {
Stream<Student> stream = Stream.of(
new Student("张三", 21, 97D),
new Student("李四", 23, 88D),
new Student("王五", 20, 62D),
new Student("赵六", 18, 59D),
new Student("钱七", 24, 100D)
);
// 查找分数最大的student
Optional<Student> optionalStudent = stream.collect(Collectors.maxBy((s1, s2) -> {
return s1.getScore() - s2.getScore() > 0 ? 1 : -1;
}));
Student student = optionalStudent.get();
System.out.println(student);
}
}
3.1.2 获取最小值——Collectors.minBy
public class StreamCollectTest01 {
public static void main(String[] args) {
Stream<Student> stream = Stream.of(
new Student("张三", 21, 97D),
new Student("李四", 23, 88D),
new Student("王五", 20, 62D),
new Student("赵六", 18, 59D),
new Student("钱七", 24, 100D)
);
// 查找分数最小的student
Optional<Student> optionalStudent = stream.collect(Collectors.minBy((s1, s2) -> {
return s1.getScore() - s2.getScore() > 0 ? 1 : -1;
}));
Student student = optionalStudent.get();
System.out.println(student);
}
}
3.1.3 求和——Collectors.summingDouble
// 求所有分数之和
Double aDouble = stream.collect(Collectors.summingDouble(Student::getScore));
3.1.4 求平均值——Collectors.averagingDouble
// 求分数的平均值
Double aDouble = stream.collect(Collectors.averagingDouble(Student::getScore));
System.out.println(aDouble);
3.1.5 统计数量——Collectors.counting()
// 求流中一共有多少个数据
Long aLong = stream.collect(Collectors.counting());
System.out.println(aLong);
3.2 对流中的数据进行分组
当我们使用Stream流处理数据后,可以根据某个属性将数据分组
3.2.1 简单的分组——Collectors.groupingBy
方法定义:
public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) {
return groupingBy(classifier, toList());
}
例1:按年龄分组
package com.bjc.jdk8.col;
import com.bjc.jdk8.pojo.Student;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamCollectTest01 {
public static void main(String[] args) {
Stream<Student> stream = Stream.of(
new Student("张三", 21, 97D),
new Student("李四", 21, 88D),
new Student("王五", 24, 62D),
new Student("赵六", 18, 59D),
new Student("钱七", 24, 100D)
);
// 根据年龄将数据分组
Map<Integer, List<Student>> collect = stream.collect(Collectors.groupingBy(Student::getAge));
collect.forEach((k,v)->{
System.out.println("key:" + k + " value = " + v);
});
}
}
运行结果如图:
例2:按分数区间分组
package com.bjc.jdk8.col;
import com.bjc.jdk8.pojo.Student;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamCollectTest01 {
public static void main(String[] args) {
Stream<Student> stream = Stream.of(
new Student("张三", 21, 97D),
new Student("李四", 21, 88D),
new Student("王五", 24, 62D),
new Student("赵六", 18, 59D),
new Student("钱七", 24, 100D)
);
Map<String, List<Student>> map = stream.collect(Collectors.groupingBy(student -> {
if (student.getScore() > 80) {
return "优秀";
} else {
return "良";
}
}));
map.forEach((k,v) -> {
System.out.println("k:" + k + " v:" + v);
});
}
}
运行结果:
3.2.1 多级分组——Collectors.groupingBy
使用Collectors.groupingBy的重载函数,方法定义
public static <T, K, A, D> Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream) {
return groupingBy(classifier, HashMap::new, downstream);
}
例如:
package com.bjc.jdk8.col;
import com.bjc.jdk8.pojo.Student;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamCollectTest01 {
public static void main(String[] args) {
Stream<Student> stream = Stream.of(
new Student("张三", 21, 97D),
new Student("李四", 21, 88D),
new Student("王五", 24, 62D),
new Student("赵六", 18, 59D),
new Student("钱七", 24, 100D)
);
// 先根据年龄分组,在根据分数分组
Map<Integer, Map<String, List<Student>>> collect = stream.collect(Collectors.groupingBy(Student::getAge, Collectors.groupingBy(s -> {
if (s.getScore() > 80) {
return "优秀";
} else {
return "一般";
}
})));
collect.forEach((k,v)->{
System.out.println("age:" + k);
v.forEach((k1,v1)->{
System.out.println("\t" + "k1:" + k1 + " v1:" + v1);
});
});
}
}
运行结果:
3.3 对流中的数据进行分区——Collectors.partitioningBy
Collectors.partitioningBy会根据值是否为true,把集合分割为两个列表,一个true列表,一个false列表。
如图所示:
例如:
package com.bjc.jdk8.col;
import com.bjc.jdk8.pojo.Student;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamCollectTest01 {
public static void main(String[] args) {
Stream<Student> stream = Stream.of(
new Student("张三", 21, 97D),
new Student("李四", 21, 88D),
new Student("王五", 24, 62D),
new Student("赵六", 18, 59D),
new Student("钱七", 24, 100D)
);
Map<Boolean, List<Student>> map = stream.collect(Collectors.partitioningBy(s -> {
return s.getScore() > 80;
}));
map.forEach((k,v) -> {
System.out.println("k:" + k + " v:" + v);
});
}
}
运行结果:
从中我们可以发现,分区其实就是一种特殊发分组。
3.4 对流中的数据进行拼接——Collertors.joining
Collertors.joining会根据指定的连接符,将所有的元素连接成一个字符串。
例如:
package com.bjc.jdk8.col;
import com.bjc.jdk8.pojo.Student;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamCollectTest01 {
public static void main(String[] args) {
Stream<Student> stream = Stream.of(
new Student("张三", 21, 97D),
new Student("李四", 21, 88D),
new Student("王五", 24, 62D),
new Student("赵六", 18, 59D),
new Student("钱七", 24, 100D)
);
String collect = stream.map(Student::getName).collect(Collectors.joining(","));
System.out.println(collect);
}
}
运行结果: