IntStream intStream = Stream.of(1, 2, 3, 4, 5).mapToInt(Integer::intValue);
intStream.filter(n -> n > 3).forEach(System.out::println);
intStream.filter(n -> n > 3).count;
intStream.filter(n -> n > 3).reduce(0, Integer::sum);
对流操作完成之后,如果需要将流的结果保存到数组或集合中,可以收集流中的数据
Stream流中的结果到集合中
Stream流提供 collect 方法,其参数需要一个 java.util.stream.Collector 接口对象来指定收集到哪 种集合中。java.util.stream.Collectors 类提供一些方法,可以作为 Collector`接口的实例:
- public static Collector> toList() :转换为 List 集合。
- public static Collector> toSet() :转换为 Set 集合。
下面是这两个方法的基本使用代码:
// 将流中数据收集到集合中
@Test
public void testStreamToCollection() {
Stream<String> stream = Stream.of("aa", "bb", "cc");
// List<String> list = stream.collect(Collectors.toList());
// Set<String> set = stream.collect(Collectors.toSet());
ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
HashSet<String> hashSet = stream.collect(Collectors.toCollection(HashSet::new));
}
Stream流中的结果到数组中
Stream提供 toArray 方法来将结果放到一个数组中,返回值类型是Object[]的:
Object[] toArray();
其使用场景如:
@Test
public void testStreamToArray() {
Stream<String> stream = Stream.of("aa", "bb", "cc");
// Object[] objects = stream.toArray();
// for (Object obj : objects) {
// System.out.println();
// }
String[] strings = stream.toArray(String[]::new);
for (String str : strings) {
System.out.println(str);
}
}
对流中数据进行聚合计算
当我们使用Stream流处理数据后,可以像数据库的聚合函数一样对某个字段进行操作。比如获取最大值,获取最小 值,求总和,平均值,统计数量。
@Test
public void testStreamToOther() {
Stream<Student> studentStream = Stream.of(
new Student("赵丽颖", 58, 95),
new Student("杨颖", 56, 88),
new Student("迪丽热巴", 56, 99),
new Student("柳岩", 52, 77));
// 获取最大值
Optional<Student> collect = studentStream.collect(Collectors.maxBy((o1, o2) ->
o1.getSocre() - o2.getSocre()));
// 获取最小值
Optional<Student> collect = studentStream.collect(Collectors.minBy((o1, o2) ->
o1.getSocre() - o2.getSocre()));
// System.out.println(collect.get());
// 求总和
int sumAge = studentStream.collect(Collectors.summingInt(s -> s.getAge()));
System.out.println("sumAge = " + sumAge);
//平均值
double avgScore = studentStream.collect(Collectors.averagingInt(s -> s.getSocre()));
System.out.println("avgScore = " + avgScore);
// 统计数量
Long count = studentStream.collect(Collectors.counting());
System.out.println("count = " + count);
}
对流中数据进行分组
当我们使用Stream流处理数据后,可以根据某个属性将数据分组:
// 分组
@Test
public void testGroup() {
Stream<Student> studentStream = Stream.of(
new Student("赵丽颖", 52, 95),
new Student("杨颖", 56, 88),
new Student("迪丽热巴", 56, 55),
new Student("柳岩", 52, 33));
// Map<Integer, List<Student>> map =
studentStream.collect(Collectors.groupingBy(Student::getAge));
// 将分数大于60的分为一组,小于60分成另一组
Map<String, List<Student>> map = studentStream.collect(Collectors.groupingBy((s) ->
{
if (s.getSocre() > 60) {
return "及格";
} else {
return "不及格";
}
}));
map.forEach((k, v) -> {
System.out.println(k + "::" + v);
});
}
效果:
不及格::[Student{name='迪丽热巴', age=56, socre=55}, Student{name='柳岩', age=52, socre=33}]
及格::[Student{name='赵丽颖', age=52, socre=95}, Student{name='杨颖', age=56, socre=88}]
对流中数据进行多级分组
还可以对数据进行多级分组:
// 多级分组
@Test
public void testCustomGroup() {
Stream<Student> studentStream = Stream.of(
new Student("赵丽颖", 52, 95),
new Student("杨颖", 56, 88),
new Student("迪丽热巴", 56, 99),
new Student("柳岩", 52, 77));
Map<Integer, Map<String, List<Student>>> map =
studentStream.collect(Collectors.groupingBy(s -> s.getAge(), Collectors.groupingBy(s -> {
if (s.getSocre() >= 90) {
return "优秀";
} else if (s.getSocre() >= 80 && s.getSocre() < 90) {
return "良好";
} else if (s.getSocre() >= 80 && s.getSocre() < 80) {
return "及格";
} else {
return "不及格";
}
})));
map.forEach((k, v) -> {
System.out.println(k + " == " + v);
});
}
效果:
52 == {不及格=[Student{name='柳岩', age=52, socre=77}], 优秀=[Student{name='赵丽颖', age=52,socre=95}]}56 == {优秀=[Student{name='迪丽热巴', age=56, socre=99}], 良好=[Student{name='杨颖', age=56,socre=88}]}
对流中数据进行分区
Collectors.partitioningBy 会根据值是否为true,把集合分割为两个列表,一个true列表,一个false列表。
// 分区@Testpublic void testPartition() { Stream<Student> studentStream = Stream.of( new Student("赵丽颖", 52, 95), new Student("杨颖", 56, 88), new Student("迪丽热巴", 56, 99), new Student("柳岩", 52, 77)); // partitioningBy会根据值是否为true,把集合分割为两个列表,一个true列表,一个false列表。 Map<Boolean, List<Student>> map = studentStream.collect(Collectors.partitioningBy(s -> s.getSocre() > 90)); map.forEach((k, v) -> { System.out.println(k + " == " + v); });}
效果:
false == [Student{name='杨颖', age=56, socre=88}, Student{name='柳岩', age=52, socre=77}]true == [Student{name='赵丽颖', age=52, socre=95}, Student{name='迪丽热巴', age=56, socre=99}]
对流中数据进行拼接
// 拼接@Testpublic void testJoining() {Stream<Student> studentStream = Stream.of( new Student("赵丽颖", 52, 95), new Student("杨颖", 56, 88), new Student("迪丽热巴", 56, 99), new Student("柳岩", 52, 77)); String collect = studentStream .map(Student::getName) .collect(Collectors.joining(">_<", "^_^", "^v^")); System.out.println(collect);}
效果:
^_^赵丽颖>_<杨颖>_<迪丽热巴>_<柳岩^v^
小结
收集Stream流中的结果
- 到集合中: Collectors.toList()/Collectors.toSet()/Collectors.toCollection()
- 到数组中: toArray()/toArray(int[]::new)
聚合计算:
Collectors.maxBy/Collectors.minBy/Collectors.counting/Collectors.summingInt/Collectors.averagingInt
- 分组: Collectors.groupingBy
- 分区: Collectors.partitionBy
- 拼接: Collectors.joingin