正文
说来惭愧,14年的时候Java8刚推出的时候我就安装了,但是确一直没有能学习新的特性。
前段时间学习了Stream API,对于数据的处理或是遍历是真的方便,原来一段段的for循环代码可以用一句优雅的代码取代了。
废话少说,看代码吧。
比如在Java8之前遍历String大概类似这样:
String s="testing";
for(int i=0;i<s.length();i++)
{
char c=s.charAt(i);
System.out.print(c);
}
用Stream API就是一句代码:
String s = "testing" ;
s.chars().mapToObj(c -> (char)c).forEach(System.out::println);
需要说明的是直接foreach打印出来的是字符码,所以需要mapToObj方法将每一个字符码都转为char类型。
流程
要注意的是stream API的中间操作并不会立即执行,调用中间操作只会生成一个标记了该操作的stream,最后调用结束操作时才会执行所用操作。
创建流
- 通过 Collection 系列集合提供的方法 stream() 或者 parallelStream()
- 由数组创建流
通过 Arrays中的静态方法 stream() 创建数据源 。
static Stream stream(T[] array): 返回一个流
```
Integer[] num = new Integer[10];
Stream<Integer> stream = Arrays.stream(num);
```
- 由值创建流
可以使用静态方法 Stream.of(), 通过显示值 创建一个流。它可以接收任意数量的参数
public static< T> Stream< T> of(T… values) : 返回一个流 - 创建无限流
迭代:public static< T> Stream< T> iterate(final T seed, final UnaryOperator< T> f)
生成:public static< T> Stream< T> generate(Supplier< T> s)
倒计时:
生成随机数:Stream.iterate(10,(x)->x-1).limit(10).forEach(System.out::println);
Stream.generate(Math::random).limit(1).forEach(System.out::println);
筛选与切片
方法 | 描述 |
---|---|
filter(Predicate p) | 从流中过滤掉元素 |
distinct | 去掉重复元素 |
limit(long maxSize) | 和sql差不多,限制元素 |
skip(long n) | 跳过元素,元素不够则返回空stream |
映射
方法 | 描述 |
---|---|
map(Function f) | 接收一个函数作为参数,该函数会被应用到每个元 素上,并将其映射成一个新的元素 |
mapToDouble(ToDoubleFunction f) | 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的 DoubleStream |
mapToInt(ToIntFunction f) | 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的 IntStream |
mapToLong(ToLongFunction f) | 接收一个函数作为参数,该函数会被应用到每个元 素上,产生一个新的 LongStream |
flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 |
结束操作
方法 | 描述 |
---|---|
allMatch(Predicate p) | 是否匹配所有元素 |
anyMatch(Predicate p) | 是否至少匹配一个元素 |
noneMatch(Predicate p) | 是否没有匹配所有元素 |
findFirst() | 返回第一个元素 |
findAny() | 返回任意元素 |
count() | 返回元素个数 |
max(Comparator c) | 返回流中最大值 |
min(Comparator c) | 返回流中最小值 |
forEach(Consumer c) | 迭代 |
原理
在网上看到了这篇blog,对其原理有了大概的了解。
总结
Stream API中大量使用了lambda表达式,对于我这种曾经算半个ruby程序员的人来说还是适应得比较快的。
想起来也是感触万分,这段并不成功的求职经历归根结底有客观原因当然更多的是个人的原因。
- stream并不是数据结构
- 不支持像数组一样的索引访问
- 中间操作的惰性化
- 能并行执行且不需要自己写多线程实现,用parallelStream