一、Stream
A sequence of elements supporting sequential and parallel aggregate operations
Stream是一组用来处理数组、集合的API
Java8之所以费这么大功夫引入函数式编程,原因有二:
(1)代码简洁函数式编程写出的代码简洁且意图明确,使用stream接口让你从此告别for循环
(2)多核友好,java函数式编程使得编写并行程序从未如此简单,你需要的全部就是调用一下parallel()方法
1、特性:
1、不是数据结构,没有内部存储
2、不支持索引访问
3、延迟计算
4、支持并行
5、很容易生成数组或集合(List,Set)
6、支持过滤,查找,转换;汇总,聚合等操作
2、Stream运行机制
1、Stream分为 源source,中间操作,终止操作
2、流的源可以是一个数组,一个集合,一个生成器方法,一个I/O通道等等
3、一个流可以有零个或者多个中间操作,每个中间操作都会返回一个新的流,供下一个操作使用,一个流只会有一个终止操作
4、Stream只有遇到终止操作,它的源才开始执行遍历操作
二、Stream的创建
1、通过数组
2、通过集合
3、通过Stream.generate方法来创建
4、通过Stream.iterate方法来创建
5、其他API创建
package com.msbline.stream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StreamDemo {
//通过数组来生成
static void gen1(){
String[] args = {"a","b","c","d"};
Stream stream = Stream.of(args);
stream.forEach(System.out::println);
}
//通过集合来生成
static void gen2(){
List list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
Stream stream = list.stream();
stream.forEach(System.out::println);
}
//通过generate生成
static void gen3(){
Stream stream = Stream.generate(() ->1);
// stream.limit(3);
stream.limit(3).forEach(System.out::println);
}
//使用iterator
static void gen4(){
Stream stream = Stream.iterate(1, x -> x + 1);
stream.limit(10).forEach(System.out::println);
}
//其他
static void gen5(){
String str = "abcdefg";
IntStream stream = str.chars();
stream.forEach(System.out::println);
}
public static void main(String[] args) {
//生成操作
gen1();
System.out.println("gen2--------------------");
gen2();
System.out.println("gen3--------------------");
gen3();
System.out.println("gen4---------------------");
gen4();
System.out.println("gen5---------------------");
gen5();
}
}
三、Stream常用的API
1、中间操作
(1)过滤filter
(2)去重distinct
(3)排序sorted
(4)截取limit、skip
(5)转换map/flatMap
(6)其他peek
2、终止操作
(1)循环forEach
(2)计算min、max、count、average
(3)匹配anyMatch、allMatch、noneMatch、findFirst、findAny
(4)汇聚reduce
(5)收集器toArray collect
3、示例
public static void main(String[] args) {
//中间操作:如果调用方法之后返回的结果是Stream对象就意味着是一个中间操作
Arrays.asList(1,2,3,4,5).stream().filter((x)->x%2==0)
.forEach(System.out::println);
//求出结果集中所有偶数的和
int count = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream().filter((x) -> x % 2 == 0)
.mapToInt(x->x).sum();
System.out.println(count);
//求集合中的最大值
List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
Optional max = list.stream().max((a, b) -> a - b);
System.out.println(max.get());
//求最小值
Optional min = list.stream().min((a, b) -> a-b);
System.out.println(min.get());
Optional any = list.stream().filter(x -> x % 2 == 0).findAny();
System.out.println(any.get());
Optional first = list.stream().filter(x -> x % 2 == 0).findFirst();
System.out.println(first.get());
List list1 = Arrays.asList(1, 3, 5, 6);
Stream integerStream = list1.stream().filter(x -> {
System.out.println("运行方法");
return x % 2 == 0;
});
// System.out.println(integerStream.findFirst().get());
System.out.println(integerStream.findAny().get());
System.out.println("---------------------------------");
//获取最大值和最小值,但是不使用min和max方法
List list2 = Arrays.asList(1, 3, 5, 6);
Optional min1 = list2.stream().sorted().findFirst();
System.out.println(min1.get());
Optional max1 = list2.stream().sorted((a, b) -> b - a).findFirst();
System.out.println(max1.get());
Arrays.asList("java","c#","python","scala").stream()
.sorted().forEach(System.out::println);
System.out.println("----------------------------------");
Arrays.asList("java","c#","python","scala").stream()
.sorted((a,b)->a.length()-b.length()).forEach(System.out::println);
//想将集合中的元素进行过滤同时返回一个集合
System.out.println("----------------------------------");
List list3 = Arrays.asList(1, 2, 3, 4, 5, 6);
List collect = list3.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
collect.forEach(System.out::println);
System.out.println("-----------------------");
//去重操作
Arrays.asList(1,2,3,3,3,4,5).stream().distinct().forEach(System.out::println);
System.out.println("-----------------------");
Arrays.asList(1,2,3,3,3,4,5).stream().collect(Collectors.toSet()).forEach(System.out::println);
System.out.println("-----------------------");
//打印20-30这样的集合数据
Stream.iterate(1,x->x+1).limit(50).skip(20).limit(10).forEach(System.out::println);
System.out.println("------------------------");
String str = "11,22,33,44,55";
int sum = Stream.of(str.split(",")).mapToInt(x -> Integer.parseInt(x)).sum();
System.out.println(sum);
int sum1 = Stream.of(str.split(",")).map(x -> Integer.valueOf(x)).mapToInt(x -> x).sum();
System.out.println(sum1);
int sum2 = Stream.of(str.split(",")).mapToInt(Integer::valueOf).sum();
System.out.println(sum2);
int sum3 = Stream.of(str.split(",")).map(Integer::valueOf).mapToInt(x -> x).sum();
System.out.println(sum3);
System.out.println("-------------");
//创建一组自定义对象
String str2 = "java,scala,python";
Stream.of(str2.split(",")).map(x->new Person(x)).forEach(System.out::println);
System.out.println("-------------");
Stream.of(str2.split(",")).map(Person::new).forEach(System.out::println);
System.out.println("-------------");
Stream.of(str2.split(",")).map(x->Person.build(x)).forEach(System.out::println);
System.out.println("-------------");
Stream.of(str2.split(",")).map(Person::build).forEach(System.out::println);
System.out.println("-------------------");
//将每个值都打印出来,同时算出最终的求和结果
String str1 = "11,22,33,44,55";
int sum4 = Stream.of(str1.split(",")).peek(System.out::println).mapToInt(Integer::valueOf).sum();
System.out.println(sum4);
System.out.println(list.stream().allMatch(x -> x == 0));
System.out.println(list.stream().allMatch(x -> x >= 0));
System.out.println(list.stream().anyMatch(x -> x >= 0));
}