java8 stream的提出可以说改变了编程的一种思维。
sql化的表达
sql的表达是一种比较容易上手的语法结构,一直维护做什么的动作。
例如
select avg(num) from table1 where sum>5
对table里的num字段筛选,选出大于5的数字然后求平均值。
对于没有stream的java语言想表达这个。
public static int cal(int[] data) {
int totalNum = 0;
int count = 0;
for (int datum : data) {
if (datum > 5) {
count++;
totalNum += datum;
}
}
return totalNum / count;
}
我们先得明白如何求平均,那是总数除以总个数,有筛选条件要以一个过滤,先去求出个数和总和。最后再来计算出平均值。
换成stream表达呢
public static int calStream(int[] data) {
double asDouble = Arrays.stream(data).filter((num) -> num > 5).average().getAsDouble();
return new Double(asDouble).intValue();
}
这里可能说是用了average这种内置的方法。所以显得很简洁了。如果抽象出一个方法来,也可以这样。我们来看看average的实现。
public final OptionalDouble average() {
long[] avg = collect(() -> new long[2],
(ll, i) -> {
ll[0]++;
ll[1] += i;
},
(ll, rr) -> {
ll[0] += rr[0];
ll[1] += rr[1];
});
return avg[0] > 0
? OptionalDouble.of((double) avg[1] / avg[0])
: OptionalDouble.empty();
}
底层是一个collect的实现,第一个参数表示最终返回一个long的数组,里面有两个元素。第二个表示对于过来的元素的操作。和我们上面的代码表意是相同的。
count++;
totalNum += datum;
第三个操作,就是说我们要如何进行每个小的模块的组合。对于我们的用例来说,第三个步骤似乎是没有必要的。
现在如何说我们改动并行的程序来做这个事情呢,
public static int calStream(int[] data) {
double asDouble = Arrays.stream(data).parallel().filter((num) -> num > 5).average().getAsDouble();
return new Double(asDouble).intValue();
}
想并行化的话,直接加个parallel就可以了。
如果原来的java的写法。得先把数据平均分散多分,最好一个线程一段数据,然后每个数据进行过滤,然后求各自的sum和count。最后合并的时候,组合一下,每个的数据再一起加一下。
看看操作是不是和collect描述的一样的。
通过stream的编写方式不断的编写每个步骤要做什么,而且在大的框架下,保证了每个任务操作的并发性,最终保证了代码从串行到并行的转化。
stream的缺陷
上面提到sql的表达。我们也发现。下面是无法实现的。
select avg(num),max(num) from table1 where sum>5
目前的stream只是针对一份数据的操作。如果结果有多个,例如上面的有均值,有最大值,同时操作多个结果,目前是无法做到的。单纯的依靠sql并不能解决stream的所有的问题。
方便的转化操作
stream还带来了一个好处就是转化非常方便。例如我们用dbutil的工具,传入参数是一个Object[][]的二维数组。自己写还要先计算大小等等。如果用stream就很方便。
int[][] ints = stringList.stream().map(s -> Integer.parseInt(s)).map(s -> new int[]{s}).toArray(int[][]::new);
这里把stream转化成对应的int,然后把每个元素作为一位数组,最终所有的一维数组组合成一个二维数组。
这里把非常复杂的代码转化成了一行。
小结
stream可以理解为单一结构的sql语法。这样可以快速的帮我们在stream的框架下进行求解操作。但是无法针对多结果的情况。
利用stream可以很快的把一个单线程程序,转化为多线程,加速的并发编程的效率。
数据的转化等操作,stream带来了极大的方便。