Stream是java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找,过滤和映射数据等操作
使用Stream Api 对集合数据进行操作,就类似于使用SQL执行的数据库查询,也可以使用Stream API 来执行并操作,Stream API提供了一种高效且易于使用的处理数据的方式 。
Stream 和Collection 集合的区别,Collection 是一种静态的内存数据结构,而Stream 是有关计算的。前者是主要面前内存,存储在内存中,后者主要是面向CPU,通过CPU实现计算的。
集合讲的是数据,Stream讲的是计算!
1.创建Stream
一个数据源 ,获取一个流
2.中间操作
一个中间操作链,对数据源的数据进行处理
3.终止操作
一旦执行种植操作,就执行中间操作连,并产生结果,之后不会再使用。
若不执行终止操作 则不会进行中间操作,也就不会对数据进行处理。
方式一 :通过集合
List<Object> list =new ArrayList<>();
Stream<Object> stream = list.stream();//返回一个顺序流 (按集合中的顺序来)
Stream<Object> stream1 = list.parallelStream();//返回一个并行流(向多个线程一样执行)
方式二:通过数组
int [] arr = new int[]{1,2,3,4,5,6};
IntStream stream2 = Arrays.stream(arr); //返回的类型是根据传入的类型决定的
方式三 通过Stream的of()
Stream<Integer> stream3 = Stream.of(1, 2, 3, 4, 5);
方式四:创建无限流(了解一下)
方法 | 描述 |
---|---|
filter(Predicate p) | 接收Lambda,从流中排除某些元素 |
distinct() | 筛选,通过流所生成元素的 hashCode() 和 equals()去除重复元素 |
limit(long maxSize) | 截断流,使其元素不超过给定数量 |
skip(long n) | 跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补 |
filter
int [] arr = new int[]{1,2,3,4,5,6};
IntStream stream2 = Arrays.stream(arr);
stream2.filter(value -> value>2).forEach(System.out::println);
注意我这里用同一个stream2 是因为我把上面那个注释了 不然的话一个Strem 在终止操作后就不存在了 不能重复使用
limit
IntStream stream2 = Arrays.stream(arr);
stream2.limit(3).forEach(System.out::println);
skip: 跳过几个元素
IntStream stream2 = Arrays.stream(arr);
stream2.skip(3).forEach(System.out::println);
distinct
int [] arr = new int[]{1,2,3,4,4,5,6};
IntStream stream2 = Arrays.stream(arr);
stream2.distinct().forEach(System.out::println);
方法 | 描述 |
---|---|
map | 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素 |
map ToDouble | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的DoubleStream |
map ToInt | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的IntStream |
map ToLong | 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的LongStream |
flatMap | 接收一个函数作为参数,讲流中的每个值都换成一个流,然后把所有流连接成一个流 |
map
自动遍历 放在str中
String [] arr = new String[]{"a","b","c","d","e","f"};
Stream<String> stream = Arrays.stream(arr);
stream.map(str->str.toUpperCase()).forEach(System.out::println);
练习 : 获得员工姓名长度大于三的员工姓名
1.首先先映射员工姓名 在进行过滤
List<Employee> employee =new ArrayList<>();
employee.stream().map(e->e.getName()).filter(name->name.length()>3).foreach(System.out::println)
方法 | 描述 |
---|---|
sorted() | 产生一个新流,其中按自然顺序排序 |
sorted(Com parator com) | 产生一个新流 |
Stream<String> stream = Arrays.stream(arr);
stream.sorted().forEach(System.out::println);
对象类型的想要进行排序 需要实现Comparable接口 或者定制排序
这里假设有个员工类集合 需要按照 年龄进行排序
employees.stream().sorted((e1,e2)->{
return Integer.compare(e1.getAge(),e2.getAge());
}).forEach(System.out::println)
方法 | 描述 |
---|---|
allMatch | 检查是否匹配所有元素 |
anyMatch | 检查是否至少匹配一个元素 |
noneMatch | 检查是否没有匹配所有元素 |
findFirst() | 返回第一个元素 |
findAny() | 返回当前流中的任意元素 |
count | 返回流中元素总个数 |
max() | 返回流中最大值 |
min() | 返回流中最小值 |
foreach() | 内部迭代 |
例子1 : 判断是否所有员工的年龄都大于18
boolean allMatch=employees.stream().allMatch(e->e.getAge()>18);
方法 | 描述 |
---|---|
reduce(T iden,BinaryOperator b) | 可以将流中元素反复结合起来 得到一个值 T |
reduce(BinaryOperator b) | 可以将可以将流中元素反复结合起来 得到一个值 Optional< T> |
例子
计算 1- 10自然数的和
List<Integer> list = Arrays.alist(1,2,3,4,5,6,7,8,9,10);
Integer sum=list.stream().reduce(0,Integer::sum);
练习2: 计算公司所有员工工资总和
employees.stream().map(Employee:: getSalary).reduce(Double::sum)
employees.stream().map(Employee:: getSalary).reduce((d1,d2)->d1+d2)
方法 | 描述 |
---|---|
collect(Collection c ) | 将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法 |
Collector 接口中的方法实现决定了如何对流执行收集的操作 如收集到(List ,Set Map)
练习: 查找工资大于6000的员工 结果返回一个List
employee.stream().filter(e- > e.getSalary()>6000).collect(Collectors.toList())