Stream 流真好用
Java 8 API 添加了一个新的抽象称为 Stream 流,可以以一种声明的方式处理数据。
Stream 使用一种类似 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达。
这种风格将要处理的元素集合看作成一种流,流在管道中传输,并可以在管道的节点进行处理,如筛选、排序、聚合等;最后由最终操作得到前面处理的结果。
简单案例
老方法求一个数组的和
public static void main(String[] args) {
int[] nums={1,2,3};
int sum = 0;
for(int a : nums){
sum += a;
}
System.out.println(sum);
}
用 Stream 来操作
public static void main(String[] args) {
int[] nums={1,2,3};
int sum = IntStream.of(nums).parallel().sum();
System.out.println(sum);
}
如果想实现并发的话,直接加上 parallel()
方法即可。
稍微复杂的案例
public static void main(String[] args) {
String str = "apple orange pie dog cat";
Stream.of(str.split(" ")).filter(s -> s.length() > 4)
.map(s -> s.length()).forEach(System.out::println);
}
简单来分析一下:
-
从字符串中创建出流对象:
Stream<String> split = Stream.of(str.split(" "));
-
通过流对象的 API 执行中间操作(filter),返回的还是流对象
Stream<String> filterStream = split.filter(s -> s.length()>4);
-
通过返回的流对象再执行中间操作(map),返回的还是流对象
Stream<Integer> integerStream = filterStream.map(s -> s.length());
-
最后进行结果打印
integerStream.forEach(System.out::println);
最后贴一下完整代码
public static void main(String[] args) {
String str = "apple orange pie dog cat";
Stream.of(str.split(" ")).filter(s -> s.length() > 4)
.map(s -> s.length()).forEach(System.out::println);
//从字符串中创建出流对象:
Stream<String> split = Stream.of(str.split(" "));
//通过流对象的 API 执行中间操作(filter),返回的还是流对象
Stream<String> filterStream = split.filter(s -> s.length()>4);
//通过返回的流对象再执行中间操作(map),返回的还是流对象
Stream<Integer> integerStream = filterStream.map(s -> s.length());
//两种打印方式都可以,双引号方式为Lambda表达式的简写方式
// integer.forEach(a -> System.out.println(a));
integerStream.forEach(System.out::println);
}
/*res:
5
6
5
6
开发中使用案例
先定义一个学生类
class Student{
private int id;
private int age;
private String name;
private String grade;
private Boolean status;
public Student(int id, int age, String name, String grade, boolean status) {
this.id = id;
this.age = age;
this.grade = grade;
this.status = status;
this.name = name;
}
public int getAge() {
return this.age;
}
public String getName(){
return this.name;
}
public String getGrade(){
return this.grade;
}
public String toString(){
return (id+" "+age+" "+name+" "+grade+" "+status);
}
}
创建4个student放入列表
常规方法:
直接创建一个List,然后一个一个的add进去
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student(1,19,"张三","M",true));
students.add(new Student(2,18,"李四","M",false));
students.add(new Student(3,21,"王五","F",true));
students.add(new Student(4,20,"赵六","F",false));
}
Stream 流方法
public static void main(String[] args) {
List<Student> student = Stream.of(stu1,stu2,stu3,stu4).collect(Collectors.toList());
for(Student stu : student){
System.out.println(stu.toString());
}
}
取对象的某一列
拿上面的students
举例
普通方法
List<String> studentNameList = new ArrayList<>();
for(Student stu : student){
studentNameList.add(stu.getName());
}
Stream流方法
List<String> studentNameList = student.stream().map(Student::getName).collect(Collectors.toList());
过滤(根据判断条件筛选出目标对象)
继续拿上面的students
举例
筛选出,年龄小于20的所有学生
普通方法
List<Student> newUserList = new ArrayList<>();
for(Student stu : student)
{
if(stu.getAge()<20){
newUserList.add(stu);
}
}
Stream 流方法
List<Student> stu = students.stream()
.filter(student -> student.getAge()<20)
.collect(Collectors.toList());
Map 和 List 互转
list 转 map
普通遍历方法:
Map<String,Object> stuMap = new HashMap<>();
for(Student stu : students){
stuMap.put(stu.getName(),stu);
}
Stream 流方法
Map<String,Object> stuMap = students.stream()
.filter(stu -> stu.getName() != null)
.collect(Collectors.toMap(Student::getName, Function.identity(),(key1,key2)->key2));
map 转 list
普通遍历方法:
List<Student> stuList = new ArrayList<>();
for(String stuName : stuMap.keySet()){
stuList.add((Student) stuMap.get(stuName));
}
Stream 流方法
List<Student> stuList = stuMap.entrySet()
.stream().map(e -> e.getValue())
.collect(Collectors.toList());