Stream流

stream流,是在java8中,由lambda表达式所带来的一种新的函数是编程模式,可以用来解决一些已有的集合类型的弊端。

1.stream流与传统集合的便利方式的区别

传统遍历方式

 1 public static void main(String[] args) {
 2         //遍历输出名字中含有七的并且名字长度为3的人
 3         List<String> list = List.of("乔七七","韩七岁","零零七","鲁班七号","上官婉儿");
 4  5         List<String> newList = new ArrayList<>();
 6         //遍历list挑选出名字中带有七的
 7             for (String s : list) {
 8                 if (s.contains("七")){
 9                    newList.add(s);
10                 }
11             }
12 13             //遍历出名字长度为3的
14             for (String s : newList) {
15                 if (s.length()==3){
16                     System.out.println(s);
17                 }
18             }
19         }

stream方式

1 public static void main(String[] args) {
2         List<String> list = List.of("乔七七","韩七岁","零零七","鲁班七号","上官婉儿");
3         //筛选带七的且名字长度为3的人
4         list.stream().filter(s -> s.contains("七"))
5                      .filter(s -> s.length()==3)
6                      .forEach(System.out::println);
7     }

emmm,是不是很简单明了。

2.stream流思想原理

当对集合中的元素需要进行一系列的操作,我们可已按照需要的规则来进行处理这些集合中的数据。

Stream流-LMLPHP

在这个图中显示了过滤,映射,跳过,计数等多个环节,将这些步骤都放在一起进行一个流水线一样的操作,整个过程在一个管道中完成,将数据又由原始状态转变为需要的状态。

filtermapskip都是在对函数模型进行操作,集合元素并没有真正被处理。只有当终结方法count执行的时候,整个数据才会按照指定要求执行操作。

3.stream流中常用的方法

stream流中方法可分为两类,一种为终结方法,另外一种为非终结方法。

  • 终结方法:返回值类型不再是Stream接口自身类型的方法。

  • 非终结方法:返回值仍然是stream接口的方法,支持链式调用。

过滤:filter

filter方法将一个流转换为另外一个子集流。

Stream<T> filter(Predicate<? super T> predicate);

该接口接收一个Predicate函数式接口参数(可以是一个Lambda或方法引用)作为筛选条件。

1  public static void main(String[] args) {
2         Stream<String> stream = Stream.of("鲁班七号", "老夫子", "公孙离", "南宫", "甄姬");
3         stream.filter(s -> s.length() == 2).forEach(System.out::println);
4 5     }

截取:limit

limit方法可以对流进行截取,只取用前n个。

Stream<T> limit(long maxSize);

参数是一个long型,如果集合当前长度大于参数则进行截取;否则不进行操作

1 public class StreamLimit {
2     public static void main(String[] args) {
3         Stream<String> stream = Stream.of("鲁班七号", "老夫子", "公孙离", "南宫", "甄姬");
4         //limit截取前几个元素
5         stream.limit(3).forEach(System.out::println);
6     }
7 }
 

跳过:skip

skip方法可以跳过前几个元素,从而获取之后的元素作为一个新的流。

Stream<T> skip(long n);

如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流。


1 public class StreamSkip {
2     public static void main(String[] args) {
3         //skip跳过几个元素
4         Stream<String> stream = Stream.of("鲁班七号", "老夫子", "公孙离", "南宫", "甄姬");
5         stream.skip(2).forEach(System.out::println);
6     }
7 }

映射:map

map方法可以将需要的元素映射到另外一个集合中。

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

该接口需要一个Function函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流。

1 public class StreamMap {
2     public static void main(String[] args){
3         Stream<String> oldStream = Stream.of("1.2", "1.3", "3.5", "12.5", "65.8");
4         Stream<Double> newStream = oldStream.map(Double::parseDouble);
5         newStream.forEach(System.out::println);
6     }
7 }
 

联合concat

如果有两个流,希望合并成为一个流,那么可以使用Stream接口的静态方法concat

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)

基本使用:

1 public static void main(String[] args) {
2         //concat,合并流
3         Stream<String> wurenxiaofendui = Stream.of("孙悟空", "猪八戒", "沙和尚", "小白龙", "唐僧");
4         Stream<String> yaojingwurenzu = Stream.of("紫霞","嫦娥","小侍女","四公主","女儿国国王");
5         Stream<String> stringStream = Stream.concat(wurenxiaofendui, yaojingwurenzu);
6         stringStream.forEach(System.out::println);
7     }

计数:count

count方法用来统计个数

long count();

使用:

 1 public class ListDemo {
 2     public static void main(String[] args) {
 3  4         List<String> list = List.of("乔七七","韩七岁","零零七","鲁班七号","上官婉儿");
 5         //筛选带七的且名字长度为3的人,统计个数
 6         long count = list.stream().
 7                 filter(s -> s.contains("七")).
 8                 filter(s -> s.length() == 3).count();
 9         System.out.println(count);
10     }
11 }

遍历处理forEach

forEach,但是与for循环中的“for-each”昵称不同,该方法并不保证元素的逐一消费动作在流中是被有序执行的

void forEach(Consumer<? super T> action);

该方法接收一个Consumer接口函数,会将每一个流元素交给该函数进行处理。


1 import java.util.stream.Stream;
2 3 public class StreamForEach {
4     public static void main(String[] args) {
5 6         Stream<String>  stream = Stream.of("孙悟空", "猪八戒", "沙和尚", "小白龙", "唐僧");
7         stream.forEach(System.out::println);
8      }
9 }
01-01 00:44