JDK1.8之后,得益于lambda表达式带来的函数式编程,引入了全新的Stream概念
以前想筛选一个集合中的元素,需要遍历集合,然后判断是否满足条件再删除
可有了Stream流后,可以直接使用函数式编程的Predicate接口来筛选
集合获取流:所有的Collection 集合都可以通过stream 默认方法获取流
ArrayList<Integer> list = new ArrayList<>();
Stream<Integer> s = list.stream();
若要获取Map集合的Stream流对象,只能获取keySet集合和entrySet集合再获取Stram
数组获取流:Stream 接口的静态方法of 可以获取数组对应的流
Stream<Integer> s = Stream.of(12,4,124,12,4);
常用方法:
Stream<T> filter(Predicate<T> predicate) 过滤流内元素,返回新的Stream对象
Stream<Integer> s1 = Stream.of(12, 4, 124, 12, 4);
Stream<Integer> s2 =s1.filter((integer) -> integer > 10); //过滤掉大于10的元素
long count() 返回一个long值代表元素个数
Stream<Integer> s1 = Stream.of(12, 4, 124, 12, 4);
Stream<Integer> s2 =s1.filter((integer) -> integer > 10);
System.out.println(s2.count()); //输出:3
Stream<T> limit(long maxSize) 只取流前面的几个元素,返回新的Stream对象
Stream<Integer> s1 = Stream.of(12, 4, 124, 12, 4);
Stream<Integer> s2 = s1.limit(3); //流中剩12 4 124三个元素
Stream<T> skip(long n) 跳过前面几个元素,返回新的Stream对象
Stream<Integer> s1 = Stream.of(12, 4, 124, 12, 4);
Stream<Integer> s2 = s1.skip(3); //流中剩12 4 两个元素
<R> Stream<R> map(Function<T,R> mapper) 将Stream流的T类型转换成R类型
Stream<Integer> s1 = Stream.of(12, 4, 124, 12, 4);
Stream<String> s2 = s1.map((integer)->integer.toString()); //得到一个String类型的流对象
static <T> Stream<T> concat(Stream<T> a, Stream<T> b) 将两个流对象合成一个Stream对象
Stream<Integer> s1 = Stream.of(12, 4, 124, 12, 4);
Stream<Integer> s2 = Stream.of(62,426,5,23,5);
Stream<Integer> s3 = Stream.concat(s1,s2); //将s1和s2两个流合成一个流对象
void forEach(Consumer<T> action) 对流中元素进行逐一处理
Stream<Integer> s1 = Stream.of(12, 4, 124, 12, 4);
s1.forEach(System.out::println); //逐一打印流的元素
注意:
方法能返回一个流对象的属于函数拼接,支持链式调用,
可是一个流通过方法产生新流后,就不能再使用原来的流了!!
方法不返回流对象,则为终结方法,例:count、forEach
只要调用了终结方法,流对象就不能再使用
方法名 | 方法作用 | 是否支持链式调用 |
count | 显示流元素个数 | 否 |
forEach | 逐个处理流元素 | 否 |
filter | 过滤流中元素 | 是 |
skip | 忽略前面几个元素 | 是 |
limit | 选用前面几个元素 | 是 |
concat | 两个流对象进行拼接 | 是 |
map | 转换流对象的类型 | 是 |
集合转成Stream流对象后,可以将其转回集合或数组
public static <T> Collector<T, ?, List<T>> toList() 转换为List集合
Stream<Integer> s1 = Stream.of(12, 4, 124, 12, 4);
List<Integer> list1 = s1.collect(Collectors.toList());
System.out.println(list1);
public static <T> Collector<T, ?, Set<T>> toSet() 转换为Set集
Stream<Integer> s2 = Stream.of(1, 512, 4, 326, 2, 35, 23);
Set<Integer> set = s2.collect(Collectors.toSet());
<A> A[] toArray(IntFunction<A[]> generator) 转换为数组
Stream<Integer> s2 = Stream.of(1, 512, 4, 326, 2, 35, 23);
Integer[] arr2 = s2.toArray(Integer[]::new);
System.out.println(Arrays.toString(arr2));
使用Stream流对象,就可以很轻松的对集合或数组内的元素进行变更
不需要像传统的遍历一样,要找到元素的起止条件再对元素是否满足要求作判断
最后再讲流对象转回集合,就能达到以前传统模式完全一样的效果
串行流:
上述介绍的例子,全是串行流即使用集合对象或数组对象调用Stream()方法获取的Stream对象都是串行流
并行流:
直接获取并行流
Stream parallelStream() 返回并行流
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, 12, 4, 124, 12);
Stream<Integer> s = list.parallelStream();
间接获取并行流:串行流转换成并行流
Stream parallel() 串行流转换成并行流
Stream<Integer> s1 = Stream.of(12, 4, 124, 12, 4);
Stream<Integer> s2 = s1.parallel();