Stream流
概念
Stream流并不是Java 中IO流,而是JDK1.8 版本新引入的一种数据流操作API,它的出现得益于Lambda函数编程方式引入,目的是解决集合类库操作短板,让集合操作更加优雅。
类似于一种“流水线”操作方式
Stream流并不是一种集合,它是将特定的元素经过一定的处理包装后变为一个新的值并进行返回(注:stream流并不会改变原有的参数,而是将变化后的新值作为返回值返回)
Stream流的优势
利用代码举例来进一步理解其优势
public class Person {
private Integer id;
private String name;
private Integer age;
private Boolean gender;
public Person() {}
public Person(Integer id, String name, Integer age, Boolean gender) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
}
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 Boolean getGender() {
return gender;
}
public void setGender(Boolean gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", gender=" + gender +
'}';
}
}
//普通数组输出方法(筛选出年龄大于20岁的)
import java.util.Arrays;
public class Demo {
public static void main(String[] args) {
Person[] array = new Person[5];
for (int i = 0; i < array.length; i++) {
int age = (int) (Math.random() * 50);
array[i] = new Person(i + 1, "张" + i, age, false);
}
for (Person person : array) {
if (person.getAge() > 20){
System.out.println(person);
}
}
}
}
//利用stream流方法(筛选出年龄大于20岁的)
import java.util.Arrays;
public class Demo {
public static void main(String[] args) {
Person[] array = new Person[5];
for (int i = 0; i < array.length; i++) {
int age = (int) (Math.random() * 50);
array[i] = new Person(i + 1, "张" + i, age, false);
}
Arrays.stream(array)
.filter(person -> person.getAge() > 20)
.forEach(System.out::println);
}
}
两种情况的不同:
常规方法解决数组筛选问题时,需要收集元素、循环迭代、逻辑判断耦合再一起,当问题更加复杂或者判断筛选条件更多时,就会显得理解困难,难以切入维护
使用Stream流时,简化了代码细节、降低了业务逻辑的耦合度,代码内容荣更易理解、更容易维护
Steam流常用方法
Stream流常用的方法分为两类
1、Stream 处理数据的【中间方法】(返回类型为Stream类型,可链式调用)
2、Stream 处理数据的【最终方法/终止方法】(返回对象不再是Stream类型,根据方法的调用不同返回不同类型的数据)!注:终止方法,Stream流自动关闭,对应Stream占用的资源会被JVM回收
//代码案例
import org.junit.Test;
import java.util.ArrayList;
import java.util.stream.Stream;
public class test {
@Test
public void T(){
ArrayList<String> list = new ArrayList<>();
list.add("123");
list.add("abc");
list.add("456");
list.add("def");
Stream<String> stream = list.stream();
//执行stream中相关终止方法
stream.forEach(System.out::println);
//再次执行stream终止方法,在此之前该Stream流已关闭,被JVM回收,所以会显示客户端响应结束,不能再响应已结束后再向缓冲区输出任何内容
stream.forEach(System.out::println);
}
}
常用中间方法
Stream<T> skip(long n);
//限制跳过当前Stream流对应元素个数【掐头】(跳过n条数据)
Stream<T> limit(long n);
//限制当前Stream流对应元素总个数【去尾】(只取n条数据)
Stream<T> filter(Predicate<? super T> pre);
//判断过滤当前Stream流可以保存的数据条件,满足条件保留,不满足条件移除,过滤规则由 Predicate 接口约束(true留下,false去除)
Stream<T> distinct();
//当前Stream流中对应的所有元素去重操作
Stream<T> sorted();
//排序(要求元素有自然顺序或者遵从 Comparable 接口,默认【升序】)
Stream<T> sorted(Comparator<? super T> com);
//排序(排序规则由Comparator函数式接口规范)
Stream<R> map(Function<T, R> fun);
//数据重整,生成新的数据流(类型转换)
常用终止方法
long count();
//返回当前Stream流对应的数据元素个数
void forEach(Consumer<? super T> action)
//对Stream流中每个数据都执行传入的方法
<R, A> R collect(Collector<? super T, A, R> collector);
//Stream流中对应的存储元素转化为用户要求的集合对象
Object[] toArray();
//Stream流中存储的元素内容转换为Object类型数组返回
boolean anyMatch(Predicate<? super T> predicate);
//至少匹配一个元素
boolean allMatch(Predicate<? super T> predicate);
//匹配所有元素
Stream方法
//Stream.of();获取流式的对象
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}