|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
JAVA是一种可以撰写跨平台应用软件的面向对象的程序设计语言,由升阳(SunMicrosystems)公司的詹姆斯·高斯林(JamesGosling)等人于1990年代初开发。Java8引进了全新的StreamAPI。这里的Stream和I/O流分歧,它更像具有Iterable的汇合类,但举动和汇合类又有所分歧。
StreamAPI引进的目标在于填补Java函数式编程的缺点。关于良多撑持函数式编程的言语,map()、reduce()基础上都内置到言语的尺度库中了,不外,Java8的StreamAPI整体来说仍旧长短常完美和壮大,足以用很少的代码完成很多庞大的功效。
创立一个Stream有良多办法,最复杂的办法是把一个Collection酿成Stream。我们来看最基础的几个操纵:- publicstaticvoidmain(String[]args){List<Integer>numbers=Arrays.asList(1,2,3,4,5,6,7,8,9,10);Stream<Integer>stream=numbers.stream();stream.filter((x)->{returnx%2==0;}).map((x)->{returnx*x;}).forEach(System.out::println);}
复制代码 汇合类新增的stream()办法用于把一个汇合酿成Stream,然后,经由过程filter()、map()等完成Stream的变更。Stream另有一个forEach()来完成每一个元素的迭代。
为何不在汇合类完成这些操纵,而是界说了全新的StreamAPI?Oracle官方给出了几个主要缘故原由:
一是汇合类持有的一切元素都是存储在内存中的,十分伟大的汇合类会占用大批的内存,而Stream的元素倒是在会见的时分才被盘算出来,这类“提早盘算”的特征有点相似Clojure的lazy-seq,占用内存很少。
二是汇合类的迭代逻辑是挪用者卖力,一般是for轮回,而Stream的迭代是隐含在对Stream的各类操纵中,比方map()。
要了解“提早盘算”,无妨创立一个无量巨细的Stream。
假如要暗示天然数汇合,明显用汇合类是不成能完成的,由于天然数有没有穷多个。可是Stream能够做到。
天然数汇合的划定规矩十分复杂,每一个元素都是前一个元素的值+1,因而,天然数产生器用代码完成以下:- classNaturalSupplierimplementsSupplier<Long>{longvalue=0;publicLongget(){this.value=this.value+1;returnthis.value;}}
复制代码 重复挪用get(),将失掉一个无量数列,使用这个Supplier,能够创立一个无量的Stream:- publicstaticvoidmain(String[]args){Stream<Long>natural=Stream.generate(newNaturalSupplier());natural.map((x)->{returnx*x;}).limit(10).forEach(System.out::println);}
复制代码 对这个Stream做任何map()、filter()等操纵都是完整能够的,这申明StreamAPI对Stream举行转换并天生一个新的Stream并不是及时盘算,而是做了提早盘算。
固然,对这个无量的Stream不克不及间接挪用forEach(),如许会无穷打印下往。可是我们能够使用limit()变更,把这个无量Stream变更为无限的Stream。
使用StreamAPI,能够计划加倍复杂的数据接口。比方,天生斐波那契数列,完整能够用一个无量流暗示(受限Java的long型巨细,能够改成BigInteger):- classFibonacciSupplierimplementsSupplier<Long>{longa=0;longb=1;@OverridepublicLongget(){longx=a+b;a=b;b=x;returna;}}publicclassFibonacciStream{publicstaticvoidmain(String[]args){Stream<Long>fibonacci=Stream.generate(newFibonacciSupplier());fibonacci.limit(10).forEach(System.out::println);}}
复制代码 假如想获得数列的前10项,用limit(10),假如想获得数列的第20~30项,用:- List<Long>list=fibonacci.skip(20).limit(10).collect(Collectors.toList());
复制代码 最初经由过程collect()办法把Stream变成List。该List存储的一切元素就已是盘算出切实其实定的元素了。
用Stream暗示Fibonacci数列,其接口比任何其他接口界说都要来得复杂天真而且高效。
盘算π能够使用π的睁开式:- π/4=1-1/3+1/5-1/7+1/9-...
复制代码 把π暗示为一个无量Stream以下:- classPiSupplierimplementsSupplier<Double>{doublesum=0.0;doublecurrent=1.0;booleansign=true;@OverridepublicDoubleget(){sum+=(sign?4:-4)/this.current;this.current=this.current+2.0;this.sign=!this.sign;returnsum;}}Stream<Double>piStream=Stream.generate(newPiSupplier());piStream.skip(100).limit(10).forEach(System.out::println);
复制代码 这个级数从100项入手下手能够把π的值准确到3.13~3.15之间:- 3.15149340107099143.13178896757345453.15130116269540573.1319774911978213.15111624717868243.13215890120711833.1509382439301233.1323335927673323.15076677249083443.1325019323081857
复制代码 使用欧拉变更对级数举行减速,能够使用上面的公式:
大型的应用一般不会用这些框架(因为性能考虑);开发人员根据需要选择用一些框架,也可以不选用框架;不用框架并不代表要自己写框架;修改框架的可能性更小。 |
|