是什么
Stram流是jdk8的一个新特性,是一种高效迭代器,用于实现内部迭代,并高效处理数据。它可以实现数据过滤、数据映射、数据排序、排序等集合数据常用操作
为什么
1、可读性强,相对于for循环处理集合元素,Stream使用Lambda表达式,极大的提高了变成效率和程序可读性;
2、高效,Steam同时提供串行和并行两种模式进行汇聚操作,并行模式能够充分利用多核处理器优势,在处理大数据(大于1万)时可以提高处理效率;
3、便捷,提供了常用的聚合操作函数;
怎么用
创建一个简单的学生类,后续操作都以学生类为示范进行讲解(单类型集合和实体类集合操作相同,单类型集合无需再指定字段)
class Student {
private String name; //姓名
private Integer grade; //年级
private String desc; //备注
Student(String name,Integer grade) {
this.name = name;
this.grade = grade;
}
}
collect
聚合返回,用于指定返回的数据类型,如返回列表,拼凑字符串等,也可以用于GroudBy按指定字段分类
//比如返回List
List<Student> collectList = studentList.stream().collect(Collectors.toList());
fillter
过滤器,根据条件获取符合条件的集合元素
//筛选出一年级学生数
long count = studentList.stream().filter(student -> student.getGrade().equals(1)).count();
map
数据映射,将集合中的元素提取后重新组装成新的元素集合
//提取所有学生的名字以逗号隔开输出姓名字符串
String studentNameStr = studentList.stream().map(Student::getName).collect(Collectors.joining(","));
//根据信息自动填充备注信息
List<Student> mapList = studentList.stream()
.map(student -> {
student.setDesc(student.getName() + "是一名" + student.getGrade() + "年级学生");
return student;
})
.collect(Collectors.toList());
forEach
对每一个集合元素进行自定义操作,该操作会改变原集合数据
//如统一给学生年级数加一
studentList.stream().forEach(student -> student.setGrade(student.getGrade() + 1));
sort
数据排序,可以根据指定字段进行排序
//根据学生年级数从低到高排序
List<Student> sortedList = studentList.stream().sorted(Comparator.comparing(Student::getGrade)).collect(Collectors.toList());
statistics
数据统计,可以统计中位数,平均数等
IntSummaryStatistics statistics = studentList.stream().mapToInt(Student::getGrade).summaryStatistics();
System.out.println("学生平均年级是 : " + statistics.getAverage() + "年级");
System.out.println("学生中最高年级是 : " + statistics.getMax() + "年级");
System.out.println("学生中最低年级是 : " + statistics.getMin() + "年级");
System.out.println("学生年级数之和 : " + statistics.getSum());
parallelStream
并行操作集合数据,可以利用多线程极刑流操作,提高效率(大数据操作时使用),用法以stram一致如:
count = studentList.parallelStream().filter(student -> student.getGrade().equals(1)).count();
System.out.println("一年级学生共有" + count + "人");
demo代码
stram中除了forEach会改变原集合数据外,其余操作均不会改变原集合数据,各种操作也可以根据实际情况搭配使用
public class Test {
@Data
private static
class Student {
private String name;
private Integer grade;
private String desc;
Student(String name,Integer grade) {
this.name = name;
this.grade = grade;
}
}
public static void main(String[] args) {
Student student1 = new Student("小红",1);
Student student2 = new Student("小橙",1);
Student student3 = new Student("小黄",2);
Student student4 = new Student("小绿",3);
Student student5 = new Student("小青",4);
Student student6 = new Student("小蓝",4);
Student student7 = new Student("小紫",5);
Student student8 = new Student("小黑",5);
Student student9 = new Student("小白",6);
Student student10 = new Student("小明",6);
List<Student> studentList = new ArrayList<>();
studentList.add(student1);
studentList.add(student2);
studentList.add(student3);
studentList.add(student4);
studentList.add(student5);
studentList.add(student6);
studentList.add(student7);
studentList.add(student8);
studentList.add(student9);
studentList.add(student10);
//collect 聚合返回
//用于指定返回的数据类型,如返回列表,拼凑字符串等
//比如返回List
List<Student> collectList = studentList.stream().collect(Collectors.toList());
System.out.println(collectList);
//fillter 过滤,筛选出一年级学生数
long count = studentList.stream().filter(student -> student.getGrade().equals(1)).count();
List<Student> fillterList = studentList.stream().filter(student -> student.getGrade().equals(1)).collect(Collectors.toList());
System.out.println("一年级学生共有" + count + "人" + ",他们是" + fillterList);
//map 数据映射,将源集合中的元素取出组装成新得元素集合
//如将所有学生的名字以逗号隔开输出字符串
String studentNameStr = studentList.stream().map(Student::getName).collect(Collectors.joining(","));
System.out.println("学生名:" + studentNameStr);
//也可以将原集合数据进行操作后输出
List<Student> mapList = studentList.stream()
.map(student -> {
student.setDesc(student.getName() + "是一名" + student.getGrade() + "年级学生");
return student;
})
.collect(Collectors.toList());
System.out.println("学生名:" + mapList);
//forEach 对每一个集合元素进行自定义操作,该操作会改变原集合数据
//如统一给学生年级数加一
studentList.stream().forEach(student -> student.setGrade(student.getGrade() + 1));
//sorted 排序,可以根据指定字段进行排序(reversed倒序)
List<Student> sortedList = studentList.stream().sorted(Comparator.comparing(Student::getGrade)).collect(Collectors.toList());
System.out.println("正序输出学生信息:");
sortedList.forEach(student -> {
System.out.println(student.desc);
});
//statistics 统计,可以统计中位数,平均数等
IntSummaryStatistics statistics = studentList.stream().mapToInt(Student::getGrade).summaryStatistics();
System.out.println("学生平均年级是 : " + statistics.getAverage() + "年级");
System.out.println("学生中最高年级是 : " + statistics.getMax() + "年级");
System.out.println("学生中最低年级是 : " + statistics.getMin() + "年级");
System.out.println("学生年级数之和 : " + statistics.getSum());
//parallelStream 并行操作集合数据,可以利用多线程极刑流操作,提高效率(大数据操作时使用),用法以stram一致如:
count = studentList.parallelStream().filter(student -> student.getGrade().equals(1)).count();
System.out.println("一年级学生共有" + count + "人");
//stram中除了forEach会改变原集合数据外,其余操作均不会改变原集合数据,各种操作也可以根据实际情况搭配使用
//如筛选出三年级及以上年级同学,然后填充备注信息,并根据他们的年级数倒序排序
List<Student> tempList = studentList.stream().filter(student -> student.getGrade() >= 3).map(student -> {
student.setDesc(student.getName() + "是一名" + student.getGrade() + "年级学生");
return student;
}).sorted(Comparator.comparing(Student::getGrade).reversed()).collect(Collectors.toList());
System.out.println("倒序输出三年级及三年级以上学生信息:");
tempList.forEach(student -> {
System.out.println(student.desc);
});
}
}