Java Stream(摘自java8 API文档及stackflow)
2017-08-27 20:12
197 查看
Streamoperationsaredividedintointermediate(Stream-producing)operationsand
terminal(value-orside-effect-producing)operations.Intermediateoperationsarealwayslazy.
1、Streamscanbeobtainedinanumberofways.
· Froma Collection via
thestream()andparallelStream()methods;
· Fromanarrayvia Arrays.stream(Object[]);
· Fromstaticfactorymethodsonthestreamclasses,suchas Stream.of(Object[]), IntStream.range(int,
int) orStream.iterate(Object,UnaryOperator);
· Thelinesofafilecanbeobtainedfrom BufferedReader.lines();
· Streamsoffilepathscanbeobtainedfrommethodsin Files;
· Streamsofrandomnumberscanbeobtainedfrom Random.ints();
· Numerousotherstream-bearingmethodsintheJDK,including BitSet.stream(),Pattern.splitAsStream(java.lang.CharSequence),
and JarFile.stream().
2、Streamoperationsandpipelines
Intermediateoperationsreturnanewstream.Theyarealwayslazy.
Intermediateoperationsarefurth
ca43
erdividedinto
stateless(suchas
Traversalofthepipelinesourcedoesnotbeginuntiltheterminaloperationofthepipelineisexecuted.
2、terminaloperations
Aftertheterminaloperationisperformed,thestreampipelineisconsideredconsumed,andcannolongerbeused.
Inalmostallcases,terminaloperationsareeager,completingtheirtraversalofthedatasourceandprocessingofthepipelinebeforereturning.Onlytheterminaloperationsiterator()andspliterator()arenot.(eg:
Aboutshortcuiting:
Anintermediateoperationisshort-circuitingif,whenpresentedwithinfiniteinput,itmayproduceafinitestreamasaresult.Aterminaloperationisshort-circuitingif,whenpresentedwithinfiniteinput,itmayterminate
infinitetime.Havingashort-circuitingoperationinthepipelineisanecessary,butnotsufficient,conditionfortheprocessingofaninfinitestreamtoterminatenormallyinfinitetime.
Asideeffectisanythingamethoddoesbesidescomputingandreturningavalue.Anychangeofinstanceorclassfieldvaluesisasideeffect,asisdrawingsomethingonthescreen,writingtoafileoranetworkconnection.
Strictlyspeaking,a"function"isdefinedasnothavingsideeffects-whichiswhyJavausestheword"method"instead.Arealfunctionwithnoreturnvaluewouldbepointless.
Obviously,amethodthatdoesnothaveareturnvaluemusthavesomesortofsideeffectthatjustifiesitsexistence.Setmethodsareanexample-thesideeffectischangingtheobject'sinternalstate
ForExample:
Asideeffectiswhenamethodcallchangesaclass'sstate.So
publicclassSideEffectClass{
privateintstate=0;
publicdoSomething(intarg0){
state+=arg0;
}
}
Here,doSomething(intarg0)hasthesideeffectofchangingthestatevariable.
Whenyouthinkofaprogram,youcanthinkofitasinstructions+state+input.(指令+状态+输入)Soifthedomainofaprogramistherangeofallpossibleinput*state,andtheprogramhassideeffects,youcanseethatthecodomain(值域)
ofpossibleresultsfortheapplicationcangrowexplosively,asthenumberofsideeffectsincrease.Thismakesthepossiblestatesfortheprogramlarge,whichleadstocomplicatedtesting.Thefunctionalprogrammingparadigmisdesignedtoeliminatesideeffects.
Bymakingfunctionsfirstclasscitizensandbymakingalldeclarationsimmutablefunctionalprogrammingpreventssideeffects,whichmakesfunctionalprogrammingshineinparallelprocessing,assynchronizationissuesarereduced.
Examplefromapi:
Asanexampleofhowtotransformastreampipelinethatinappropriatelyusesside-effectstoonethatdoesnot,thefollowingcodesearchesastreamofstringsforthosematchingagivenregularexpression,andputs
thematchesinalist.
ArrayList<String>results=newArrayList<>();
stream.filter(s->pattern.matcher(s).matches())
.forEach(s->results.add(s)); //Unnecessaryuseofside-effects!
Thiscodeunnecessarilyusesside-effects.Ifexecutedinparallel,thenon-thread-safetyofArrayListwouldcauseincorrectresults,andaddingneededsynchronizationwouldcausecontention,underminingthebenefit
ofparallelism.Furthermore,usingside-effectshereiscompletelyunnecessary;theforEach()cansimplybereplacedwithareductionoperationthatissafer,moreefficient,andmoreamenabletoparallelization:
List<String>results=
stream.filter(s->pattern.matcher(s).matches())
.collect(Collectors.toList()); //Noside-effects!
stream,andothersmayrenderanorderedstreamunordered,suchasBaseStream.unordered().Further,someterminaloperationsmayignoreencounterorder,suchasforEach().
Ifastreamisordered,mostoperationsareconstrainedtooperateontheelementsintheirencounterorder;ifthesourceofastreamisaListcontaining[1,2,3],thentheresultofexecutingmap(x->x*2)must
be[2,4,6].However,ifthesourcehasnodefinedencounterorder,thenanypermutation(序列)ofthevalues[2,4,6]wouldbeavalidresult.
ormaximumofasetofnumbers,oraccumulatingelementsintoalist.Thestreamsclasseshavemultipleformsofgeneralreductionoperations,calledreduce()andcollect(),
aswellasmultiplespecializedreductionformssuchassum(),max(),orcount().
(3)areduceoperationonelementsoftype<T>yieldingaresultoftype<U>requiresthreeparameters:
[/code]
ordinaryreduction:
[/code]
ArrayList<String>strings=stream.collect(()->newArrayList<>(),
(c,e)->c.add(e.toString()),
(c1,c2)->c1.addAll(c2));
or,pullingthemappingoperationoutoftheaccumulatorfunction,wecouldexpressitmoresuccinctlyas:
List<String>strings=stream.map(Object::toString)
.collect(ArrayList::new,ArrayList::add,ArrayList::addAll);
Here,oursupplierisjustthe
tocopythestringsfromonecontainerintotheother.
terminal(value-orside-effect-producing)operations.Intermediateoperationsarealwayslazy.
1、Streamscanbeobtainedinanumberofways.
· Froma Collection via
thestream()andparallelStream()methods;
· Fromanarrayvia Arrays.stream(Object[]);
· Fromstaticfactorymethodsonthestreamclasses,suchas Stream.of(Object[]), IntStream.range(int,
int) orStream.iterate(Object,UnaryOperator);
· Thelinesofafilecanbeobtainedfrom BufferedReader.lines();
· Streamsoffilepathscanbeobtainedfrommethodsin Files;
· Streamsofrandomnumberscanbeobtainedfrom Random.ints();
· Numerousotherstream-bearingmethodsintheJDK,including BitSet.stream(),Pattern.splitAsStream(java.lang.CharSequence),
and JarFile.stream().
2、Streamoperationsandpipelines
(1)Streamoperations
1、intermediateoperationsIntermediateoperationsreturnanewstream.Theyarealwayslazy.
Intermediateoperationsarefurth
ca43
erdividedinto
stateless(suchas
filterand
map---retainnostatefrompreviouslyseenelementwhenprocessinganewelement)andstatefuloperations(suchas
distinctand
sorted---).
Traversalofthepipelinesourcedoesnotbeginuntiltheterminaloperationofthepipelineisexecuted.
2、terminaloperations
Aftertheterminaloperationisperformed,thestreampipelineisconsideredconsumed,andcannolongerbeused.
Inalmostallcases,terminaloperationsareeager,completingtheirtraversalofthedatasourceandprocessingofthepipelinebeforereturning.Onlytheterminaloperationsiterator()andspliterator()arenot.(eg:
Stream.forEachor IntStream.sum)
Aboutshortcuiting:
Anintermediateoperationisshort-circuitingif,whenpresentedwithinfiniteinput,itmayproduceafinitestreamasaresult.Aterminaloperationisshort-circuitingif,whenpresentedwithinfiniteinput,itmayterminate
infinitetime.Havingashort-circuitingoperationinthepipelineisanecessary,butnotsufficient,conditionfortheprocessingofaninfinitestreamtoterminatenormallyinfinitetime.
3、SideEffect解析(摘自stackflow)
链接:https://stackoverflow.com/questions/1073909/side-effect-whats-this?noredirect=1Asideeffectisanythingamethoddoesbesidescomputingandreturningavalue.Anychangeofinstanceorclassfieldvaluesisasideeffect,asisdrawingsomethingonthescreen,writingtoafileoranetworkconnection.
Strictlyspeaking,a"function"isdefinedasnothavingsideeffects-whichiswhyJavausestheword"method"instead.Arealfunctionwithnoreturnvaluewouldbepointless.
Obviously,amethodthatdoesnothaveareturnvaluemusthavesomesortofsideeffectthatjustifiesitsexistence.Setmethodsareanexample-thesideeffectischangingtheobject'sinternalstate
ForExample:
Asideeffectiswhenamethodcallchangesaclass'sstate.So
publicclassSideEffectClass{
privateintstate=0;
publicdoSomething(intarg0){
state+=arg0;
}
}
Here,doSomething(intarg0)hasthesideeffectofchangingthestatevariable.
Whenyouthinkofaprogram,youcanthinkofitasinstructions+state+input.(指令+状态+输入)Soifthedomainofaprogramistherangeofallpossibleinput*state,andtheprogramhassideeffects,youcanseethatthecodomain(值域)
ofpossibleresultsfortheapplicationcangrowexplosively,asthenumberofsideeffectsincrease.Thismakesthepossiblestatesfortheprogramlarge,whichleadstocomplicatedtesting.Thefunctionalprogrammingparadigmisdesignedtoeliminatesideeffects.
Bymakingfunctionsfirstclasscitizensandbymakingalldeclarationsimmutablefunctionalprogrammingpreventssideeffects,whichmakesfunctionalprogrammingshineinparallelprocessing,assynchronizationissuesarereduced.
Examplefromapi:
Asanexampleofhowtotransformastreampipelinethatinappropriatelyusesside-effectstoonethatdoesnot,thefollowingcodesearchesastreamofstringsforthosematchingagivenregularexpression,andputs
thematchesinalist.
ArrayList<String>results=newArrayList<>();
stream.filter(s->pattern.matcher(s).matches())
.forEach(s->results.add(s)); //Unnecessaryuseofside-effects!
Thiscodeunnecessarilyusesside-effects.Ifexecutedinparallel,thenon-thread-safetyofArrayListwouldcauseincorrectresults,andaddingneededsynchronizationwouldcausecontention,underminingthebenefit
ofparallelism.Furthermore,usingside-effectshereiscompletelyunnecessary;theforEach()cansimplybereplacedwithareductionoperationthatissafer,moreefficient,andmoreamenabletoparallelization:
List<String>results=
stream.filter(s->pattern.matcher(s).matches())
.collect(Collectors.toList()); //Noside-effects!
4、Ordering
Certainstreamsources(suchasListorarrays)areintrinsicallyordered,whereasothers(suchasHashSet)arenot.Someintermediateoperations,suchassorted(),mayimposeanencounterorderonanotherwiseunorderedstream,andothersmayrenderanorderedstreamunordered,suchasBaseStream.unordered().Further,someterminaloperationsmayignoreencounterorder,suchasforEach().
Ifastreamisordered,mostoperationsareconstrainedtooperateontheelementsintheirencounterorder;ifthesourceofastreamisaListcontaining[1,2,3],thentheresultofexecutingmap(x->x*2)must
be[2,4,6].However,ifthesourcehasnodefinedencounterorder,thenanypermutation(序列)ofthevalues[2,4,6]wouldbeavalidresult.
5、Reductionoperations
Areductionoperation(alsocalledafold)takesasequenceofinputelementsandcombinesthemintoasinglesummaryresultbyrepeatedapplicationofacombiningoperation,suchasfindingthesumormaximumofasetofnumbers,oraccumulatingelementsintoalist.Thestreamsclasseshavemultipleformsofgeneralreductionoperations,calledreduce()andcollect(),
aswellasmultiplespecializedreductionformssuchassum(),max(),orcount().
(1)未使用reduce:
intsum=0;
for(intx:numbers){
sum+=x;
}
(2)使用reduce
intsum=numbers.stream().reduce(0,(x,y)->x+y);
or:
intsum=numbers.stream().reduce(0,Integer::sum);
(3)areduceoperationonelementsoftype<T>yieldingaresultoftype<U>requiresthreeparameters:
<U>Ureduce(Uidentity,BiFunction<U,?superT,U>accumulator,
BinaryOperator<U>combiner);
[/code]
identityelement:bothaninitialseedvalueforthereductionandadefaultresultiftherearenoinputelements.
accumulatorfunction:takesapartialresultandthenextelement,andproducesanewpartialresult.
combinerfunction:combinestwopartialresultstoproduceanewpartialresult.
6、Mutablereduction
Amutablereductionoperationaccumulatesinputelementsintoamutableresultcontainer,suchasaCollectionorStringBuilder,asitprocessestheelementsinthestream.
ordinaryreduction:
Stringconcatenated=strings.reduce("",String::concat)[/code]
[/code]
mutablereductionoperation:collect(),itcollectstogetherthedesiredresultsintoaresultcontainersuchasaCollection.
[/code]
Acollectoperationrequiresthreefunctions:
asupplierfunction:toconstructnewinstancesoftheresultcontainer,anaccumulatorfunction:toincorporateaninputelementintoaresultcontainer,
acombiningfunction:tomergethecontentsofoneresultcontainerintoanother.Theformofthisisverysimilartothegeneralformofordinaryreduction:
<R>Rcollect(Supplier<R>supplier,
BiConsumer<R,?superT>accumulator,
BiConsumer<R,R>combiner);
Old:
ArrayList<String>strings=newArrayList<>();[/code]
for(Telement:stream){[/code]
strings.add(element.toString());[/code]
}[/code]
New:
ArrayList<String>strings=stream.collect(()->newArrayList<>(),
(c,e)->c.add(e.toString()),
(c1,c2)->c1.addAll(c2));
or,pullingthemappingoperationoutoftheaccumulatorfunction,wecouldexpressitmoresuccinctlyas:
List<String>strings=stream.map(Object::toString)
.collect(ArrayList::new,ArrayList::add,ArrayList::addAll);
Here,oursupplierisjustthe
ArrayListconstructor,theaccumulatoraddsthestringifiedelementtoan
ArrayList,andthecombinersimplyuses
addAll
tocopythestringsfromonecontainerintotheother.
相关文章推荐
- JAVA中的四舍五入,摘自api文档
- Java中如何使用帮助文档(API)
- JAVA命令制作API文档
- elasticsearch-java api之文档(document)各种操作
- 【文档摘要】J2EE Persistence - Introduction to the Java Persistence API【Entities】
- java开发API文档
- saltstack官方文档——File Server Client API
- java api文档的阅读技巧
- Java Restfull API 文档生成 Swagger UI
- 将java代码通过javadoc导出api文档
- Java如何制作帮助文档(API)
- java小例子:使用javadoc工具生成API文档
- 【文档摘要】J2EE Persistence - Introduction to the Java Persistence API【Managing Entities】
- Java文档注释【自制API】
- Sun完整发布Java API文档中文版
- java学习123之将API文档内嵌到eclipse中
- Java基础——API文档,说明书的制作
- ElasticSearch 6.x 学习笔记:28.Java API之文档批量操作
- Java API 帮助文档中英文版下载
- javadoc - Java API 文档生成器详解 转贴