栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java8 stream

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java8 stream

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带来了极大的方便。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号