Java8新特性Stream流
1. stream的介绍
stream从名称来讲是一个流,它主要作用在于对集合数据进行查找过滤一系列的操作。是一种高效且易用的数据处理方式。
Stream和Collection的区别就是:Collection只是负责存储数据,不对数据做其他处理,主要是和内存打交道。但是Stream主要是负责计算数据的,主要是和CPU打交道。
2.Stream语法
2.1前提准备
创建一个Student类,为以后操作准备
public class Student {
private Integer id;
private String name;
private Integer age;
private Double score;
public Student() {
}
public Student(Integer id, String name, Integer age, Double score) {
this.id = id;
this.name = name;
this.age = age;
this.score = score;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", score=" + score +
'}';
}
}
创建一个数据Data
public class StudentData {
public static List<Student> getStudents(){
List<Student> list = new ArrayList<>();
list.add(new Student(1,"Alice",18,99.5));
list.add(new Student(2,"Nancy",19,92.5));
list.add(new Student(3,"Tom",20,89.2));
list.add(new Student(4,"Jack",19,78.9));
list.add(new Student(5,"James",18,70.5));
list.add(new Student(6,"Helen",22,86.3));
list.add(new Student(7,"David",19,66.6));
list.add(new Student(8,"Smith",20,93.5));
list.add(new Student(9,"Ben",21,88.8));
return list;
}
}
2.2创建一个Stream流
- 通过集合创建一个stream流
List<Student> studentList = StudentData.getStudents();
// 返回一个顺序流
Stream<Student> stream = studentList.stream();
// 返回一个并行流
Stream<Student> stream2 = studentList.parallelStream();
- 通过数组来创建一个stream流
//获取一个整形Stream
int[] arr = new int[]{1,2,34,23,12,23,2,};
IntStream intStream = Arrays.stream(arr);
//获取一个Student对象Stream
Student[] students = StudentData.getStudents().toArray(new Student[0]);
Stream<Student> stream = Arrays.stream(students);
- 通过stream.of
Stream<Integer> integerStream = Stream.of(1,2,3,4,6,7,8,9);
Stream<String> stringStream = Stream.of("1","2","3","4","5","6");
Stream<Student> studentStream = Stream.of(
new Student(1,"Alice",18,88.8),
new Student(2,"James",22,90.7),
new Student(3,"Tom",20,68.6)
);
- 创建一个无限流
// 每隔5个数取一个,从0开始,无限循环
Stream.iterate(0,t->t+5).forEach(System.out::println);
// 每隔5个数取一个,从0开始,只取前五个位数
Stream.iterate(0,t->t+5).limit(5).forEach(System.out::println);
// 取出一个随机数
Stream.generate(Math::random).limit(5).forEach(System.out::println);
2.3对流进行操作
- 操作1:筛选和切片
// 过滤:过滤出所有年龄大于20岁的同学
studentList.stream().filter(s->s.getAge()>20).forEach(System.out::println);
// 截断流:筛选出前三条数据
studentList.stream().limit(3).forEach(System.out::println);
// 跳过元素:跳过前五个元素
studentList.stream().skip(5).forEach(System.out::println);
// 过滤重复数据:
studentList.stream().distinct().forEach(System.out::println);
- 操作2:映射
// map操作
List<String> list = Arrays.asList("java","python","go");
Stream<String> stringStream = list.stream();
// 每个小写字母对应一个大写的映射
// stringStream.map(s -> s.toUpperCase()).forEach(System.out::println);
Stream<Student> studentStream = StudentData.getStudents().stream();
// Stream<Integer> integerStream = studentStream.map(Student::getAge);
// integerStream.filter(age->age>20).forEach(System.out::println);
StudentData.getStudents().stream().flatMap(student -> Arrays.stream(students)).forEach(System.out::println);
- 操作3:排序
Student implements Comparable<Student>
Stream<Integer> integerStream = Stream.of(1,2,6,4,7,3,8,9);
integerStream.sorted().forEach(System.out::println);
List<Student> studentList = StudentData.getStudents();
// studentList.stream().sorted().forEach(System.out::println);
studentList.stream().sorted((e1,e2)->Integer.compare(e1.getAge(), e2.getAge())).forEach(System.out::println);
2.4匹配和查找
List<Student> list = StudentData.getStudents();
// 判断所有的学生年龄是否都大于20岁
boolean allMatch = list.stream().allMatch(s -> s.getAge() > 20);
System.out.println(allMatch);
// 判断是否存在学生的年龄大于20岁
boolean anyMatch = list.stream().anyMatch(s -> s.getAge() > 20);
System.out.println(anyMatch);
// 判断有没有叫Alice的学生,全不满足返回true
boolean noneMatch = list.stream().noneMatch(s -> s.getName().equals("Alice"));
System.out.println(noneMatch);
// 查找第一个学生
Optional<Student> first = list.stream().findFirst();
System.out.println(first);
// 查找所有学生的数量
System.out.println(list.stream().count());
System.out.println(list.stream().filter(s -> s.getAge() > 19).count());
// 查找当前流中的元素 具有不确定性,一般串行返回的是第一个数据,并行情况下可能返回不同的数据
Optional<Student> any = list.stream().findAny();
System.out.println(any);
List<String> lst1 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
List<String> lst2 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
Optional<String> findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst();
Optional<String> fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny();
System.out.println(findFirst.get()); //总是打印出David
System.out.println(fidnAny.get()); //会随机地打印出Jack/Jill/Julia
Stream<Double> doubleStream = list.stream().map(s->s.getScore());
System.out.println(doubleStream.max(Double::compare));
- 操作2:归约
// 计算数的总和
List<Integer> list = Arrays.asList(1,2,3,4,5);
System.out.println(list.stream().reduce(0, Integer::sum));
// 计算学生总分
List<Student> studentList = StudentData.getStudents();
Stream<Double> doubleStream = studentList.stream().map(Student::getScore);
System.out.println(doubleStream.reduce(Double::sum));
- 操作3:收集
@Test
public void test3() {
List<Student> studentList = StudentData.getStudents();
// 返回一个List
List<Student> listStream = studentList.stream().filter(e -> e.getAge() > 18)
.collect(Collectors.toList());
System.out.println(listStream);
// 返回一个Set
Set<Student> setStream = studentList.stream().filter(e -> e.getAge() > 18)
.collect(Collectors.toSet());
}