一、什么是流(Stream)?
是一种数据渠道,是用来操作数据源(如:数组、集合)所生成的元素序列的。
1、stream不能存储数据。
2、对stream进行操作并不会改变数据源。
3、stream是lazy的,是延迟执行的,只有需要结果是才会执行所有的操作。
stream的三个步骤:创建stream、中间操作、终端操作。
注意:中间操作并不会对stream进行任何,而是把所有的操作全放在终端操作一次性进行,称为惰性操作。
二、创建stream的常用方式
1、数组创建流
Arrays.stream(int[] array)
Arrays.stream(double[] array)
Arrays.stream(long[] array)
Arrays.stream(T[] array)
用该方法能创建处理对应基本类型的流:int,double,long类型
2、集合创建流
如:
ArrayList<String> list=new ArrayList();
Stream<String> stream=list.stream(); //创建串行流
Stream<String> stream1=list.parallelStream(); //创建并行流
3、由值创建流
使用静态方法,可以接受任意个的参数。
Stream.of(T …values)
4、由函数创建无限流(无限产生元素)
迭代:
public static< T> Stream< T> iterate( final T seed,final UnaryOperator< T> f)
生成:
public static < T> Stream< T> generate(Supplier< T> s)
Stream.iterate(1,n->n+1) //iterate
.forEach(System.out::print);
long count=Stream.generate(()->1) //generate
.count();
System.out.println(count);
三、中间操作
筛选与切片:
1、filter(Predicate p):过滤操作
2、distinct():去除重复的数
3、limit(long maxsize):限定元素的个数
4、skip(long n):跳过,扔掉前n个数,若元素不足n,则返回一个空流
int[] arr={0,1,1,2,3,4,5,6};
Arrays.stream(arr)
.distinct() //去重
.filter(n->n>2) //过滤出大于2的元素
.skip(2) //去掉前2个元素
.limit(3) //只要3个元素
.forEach(System.out::print); //遍历打印
映射:
flatmap(Function f):将流中的每一个元素换成另一个流,在把所有流连接返回一个新流
map(Function f):接受一个函数,该函数会应用到每一个元素上,并返回新元素
mapToDouble(ToDoubleFunction f)、mapToInt(ToIntFunction f)、mapToLong(ToLongFunction f)
int[] arr1={1,2,3};
char[] arr2={'a','b','c'};
String[] arr3={"A","B","C"};
Stream.of(arr1,arr2,arr3)
.flatMap(arr->Arrays.asList().stream()) //将每一个数组形成流,再将流连接起来
.forEach(System.out::print);
排序:
sorted():按照自然顺序排序
sorted(Comparator comp):按照比较其比较顺序
double[] arr={1.2 , 3.0 , 3.14 ,0 , 2.2};
Arrays.stream(arr)
.sorted() //按自然顺序排序
.forEach(n->System.out.print(n+" " ));
四、终端操作
查找和匹配:
allMatch(Predicate p):检查是否匹配所有元素
anyMatch(Predicate p):检查是否至少匹配一个元素
noneMatch(Predicate p):检查是否没有匹配的元素
findFirst():返回第一个元素
findAny():返回任意一个元素
count():返回流中的元素个数
max(Comparator c):返回流中最大值
min(Comparator c):返回流中最小值
forEach(Consumer c):内部迭代
归约:
reduce(Integeer ,BinaryOperator b):将流中的元素反复结合起来,得到一个值,返回T
reduce(BinaryOperator b):将流中的值反复结合起来,得到一个值,返回Optional< T>
reduce的作用是将流中的元素反复结合起来。可以提供一个初始值(种子),进行BinaryOperator操作后返回一个值。也可以不提供初始值,此时返回的是一个Optional<
T>。
有种子:
Integer sum=Stream.of(1,2,3,4)
.reduce(0 , Integer::sum); //将流中的元素反复相加,最后返回一个Integer值
System.out.println(sum);
无种子:
> Optional<String> optional=Stream.of("h","e","l","l","o")
> .reduce(String::concat); //将各个元素拼接成字符串,返回一个Optional类型
> System.out.println(optional.get());
>
备注:map和reduce的连接通常称为 map-reduce模式,因Google因它来进行网络搜索而出名。
收集:
collect(Collector c):将流收集,用于对元素汇总。
List list=Stream.of(1,2,3)
.collect(Collectors.toList()); //将流收集到List中
Set set=Stream.of(1,2,3)
.collect(Collectors.toSet()); //将流收集到Set中
五、并行流与串行流
并行流就是将内容分成多个数据块,并用不同的线程分别处理每一个数据块。
Stream API 可以声明的通过 parallel()与sequential()在并行流和串行流之间进行切换。
串行流:
long start=System.currentTimeMillis();
Long sum=LongStream.rangeClosed(0,1000000000L).reduce(0,Long::sum); //串行流
long end=System.currentTimeMillis();
System.out.println("time:"+(end-start)); //970
System.out.println("sum:"+sum);
并行流:
long start=System.currentTimeMillis();
Long sum=LongStream.rangeClosed(0,1000000000L).parallel()//转化成并行流
.reduce(0,Long::sum);
long end=System.currentTimeMillis();
System.out.println("time:"+(end-start)); //567
System.out.println("sum:"+sum);