StreamAPI
简介
Stream 是数据流,用于操作数据源(集合、数组等)所生成的元素序列
特点
1.Stream 自己不会存储元素。
2.Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream。
3.Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。即一旦执行终止操作,就执行中间操作链,并产生结果。
4. Stream 一旦执行了终止操作,就不能再调用其它中间操作或终止操作了。
与集合的区别
集合 是一种静态的内存数据结构,讲的是存储数据,而 Stream 是有关计算的,讲的是数据计算。前者是主要面向内存,存储在内存中,后者主要是面向 CPU,通过 CPU 实现计算,类比程序和进程。
三大操作
创建操作
中间操作
终止操作
创建操作,从数据序列中获取流
1.通过集合.stream()获取
代码示例
@Test
public void test1(){
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Stream<Integer> stream = list.stream();
System.out.println(stream);
}
2.通过Arrays.stream(数组)获取
代码示例
@Test
public void test2(){
String [] arr = {"aaa","bbb","ccc"};
Stream<String> stream = Arrays.stream(arr);
System.out.println(stream);
}
3.通过Stream.of(数据元素)获取
代码示例
@Test
public void test3(){
Stream<Integer> stream = Stream.of(1, 2, 3);
System.out.println(stream);
}
中间操作
由于Stream的中间操作是延迟执行的,所以必须在中间操作之后进行终止操作才能看到效果,所以在代码示例中使用foreach终止操作进行效果展示
代码示例,测试所用的集合
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
private Long id;
private String name;
private Integer age;
}
public class StudentUtil {
private static List<Student> studentList;
static {
studentList = new ArrayList<Student>();
Student student1 = new Student(1L,"www",19);
Student student2 = new Student(2L,"ddd",18);
Student student3 = new Student(3L,"lll",20);
studentList.add(student1);
studentList.add(student2);
studentList.add(student3);
}
public static List<Student> getStudentList(){
return studentList;
}
}
筛选
filter(Predicate p) 根据条件过滤
代码示例
@Test
public void test4(){
List<Student> studentList = StudentUtil.getStudentList();
studentList.stream().filter(student -> student.getAge() > 18).forEach(System.out::println);
}
执行结果
Student(id=1, name=www, age=19)
Student(id=3, name=lll, age=20)
distinct() 去重
代码示例
@Test
public void test5(){
List<Student> studentList = StudentUtil.getStudentList();
studentList.stream().distinct().forEach(System.out::println);
}
运行结果
Student(id=1, name=www, age=19)
Student(id=2, name=ddd, age=18)
Student(id=3, name=lll, age=20)
limit(n) 截断,取前n个元素
@Test
public void test6(){
List<Student> studentList = StudentUtil.getStudentList();
studentList.stream().limit(2).forEach(System.out::println);
}
运行结果
Student(id=1, name=www, age=19)
Student(id=2, name=ddd, age=18)
skip(n)跳过,取前n个元素之后的元素
@Test
public void test7(){
List<Student> studentList = StudentUtil.getStudentList();
studentList.stream().skip(1).forEach(System.out::println);
}
运行结果
Student(id=2, name=ddd, age=18)
Student(id=3, name=lll, age=20)
映射
map(Function f) 映射,根据输入的Function接口进行映射
代码示例
@Test
public void test8(){
List<Student> studentList = StudentUtil.getStudentList();
studentList.stream().map(student -> student.getName()).forEach(System.out::println);
}
运行结果
www
ddd
lll
flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
代码示例
@Test
public void test8(){
List<Student> studentList = StudentUtil.getStudentList();
studentList.stream().map(student -> student.getName()).forEach(System.out::println);
}
运行结果
w
d
l
排序
sorted(Compartor c)
代码示例
@Test
public void test10(){
List<Student> studentList = StudentUtil.getStudentList();
studentList.stream().sorted((s1,s2)->s1.getAge()-s2.getAge()).forEach(System.out::println);
}
运行结果
Student(id=2, name=ddd, age=18)
Student(id=1, name=www, age=19)
Student(id=3, name=lll, age=20)