Stream流是Java 8新加入的最常用的流接口,位于java.util.stream包下(java.util.stream.Stream ),这并不是一个函数式接口,接口里面包含了很多抽象方法,这些方法对于Stream流的操作都是至关重要的,最常见的方法有filter、map、foreach、count、limit、skip、concat
获取Stream流的两种方法
所有的 Collection 集合都可以通过 stream 默认方法获取流,stream()方法是Collection集合接口的一个默认方法,需要注意的是Map集合接口并不是Collection接口的子接口,所以不能直接调用stream方法获取Stream流,但是却可以分别对key和value获取Stream流;
Stream流常用方法
对于Stream流的常用方法,可以分成延迟方法和终结方法
延迟方法:返回值类型仍然是 Stream 接口自身类型的方法,支持链式调用(除了终结方法外,其余方法均为延迟方法)
终结方法:返回值类型不再是 Stream 接口自身类型的方法,因此不再支持链式调用。常见的终结方法有 count 和forEach 方法
1. foreach:遍历(对流中的元素进行遍历)
void forEach(Consumer<? super T> action); 该方法接收一个Consumer函数式接口,方法返回值是void,并非Stream接口,所以属于终结方法;
2. filter:过滤(对流进行一个过滤操作,只保留满足条件的元素)
Stream<T> filter(Predicate<? super T> predicate);该方法接收一个Predicate函数式接口,方法返回值是Stream接口,还可以进行链式调用,所以属于延迟方法;Predicate接口中的唯一抽象方法——test方法将会产生一个boolean值结果,代表指定的条件是否满足。如果结果为true,那么Stream流的 filter 方法将会留用元素;如果结果为false,那么 filter 方法将会舍弃元素;
3. map:映射(将流中的元素映射到另一个流中)
<R> Stream<R> map(Function<? super T, ? extends R> mapper); 该方法接收一个Function函数式接口,方法返回值是Stream接口,还可以进行链式调用,所以属于延迟方法;Function接口中的唯一抽象方法——apply方法接收一个参数并返回一个参数,也就是可以将一种T类型转换成为R类型,而这种转换的动作,就称为“映射”;
4. count:统计(计算流中元素个数)
long count();
该方法返回值是long不是int,这一点需要注意,另外方法返回值是long,并非Stream接口,所以属于终结方法;
5. limit:(截取流中前几个元素)
Stream<T> limit(long maxSize);
如果集合当前长度大于参数则进行截取;否则不进行操作,也就是返回原来的流对象,并不会报错
6. skip:(跳过流中前几个元素)
Stream<T> skip(long n);
如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流;
7. concat:组合(组合两个流)
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
该方法是Stream接口中的一个静态方法。
Stream流编程需要注意的点
Stream流属于管道流,只能被消费一次,也就是说第一个Stream流调用方法完毕之后,数据会流到下一个Stream流,并且该流会被关闭,再次使用该流去调用方法将会报错