ÕªÒª£ºStreams APIÊÇJava 8ÖÐз¢²¼µÄAPI£¬Ö÷ÒªÓÃÓÚ²Ù×÷collectionºÍstreamingÊý¾Ý¡£Collections API»á¸Ä±äÊý¾Ý¼¯×´Ì¬£¬¶øStreams APIÔò²»»á¡£
¡¾±àÕß°´¡¿ÔÚ֮ǰÎÄÕÂÖУ¬ÎÒÃǽéÉÜÁËJava 8ºÍScalaµÄLambda±í´ïʽ¶Ô±È¡£ÔÚ±¾ÎÄ£¬½«½øÐÐHussachai Puripunpinyo JavaºÍScala¶Ô±ÈÈý²¿ÇúµÄµÚ¶þ²¿·Ö£¬Ö÷Òª¹Ø×¢StreamºÍCollection£¬ÓÉ OneAPM¹¤³Ìʦ·Òë¡£

ÒÔÏÂΪÒëÎÄ
Ê×ÏÈ£¬Îª´ó¼Ò×öÒ»¸ö¼ò¶ÌµÄ½éÉÜ£¬collectionÊÇÓÐÏÞµÄÊý¾Ý¼¯£¬¶østreamÊÇÊý¾ÝµÄÐòÁм¯£¬¿ÉÒÔÊÇÓÐÏ޵ĻòÎÞÏ޵ġ£
Streams APIÊÇJava 8ÖÐз¢²¼µÄAPI£¬Ö÷ÒªÓÃÓÚ²Ù×÷collectionºÍstreamingÊý¾Ý¡£Collections API»á¸Ä±äÊý¾Ý¼¯×´Ì¬£¬¶øStreams APIÔò²»»á¡£ÀýÈ磬µ±Äãµ÷ÓÃCollections.sort(list)ʱ£¬¸Ã·½·¨»á¶Ô´«ÈëµÄ²ÎÊý½øÐÐÅÅÐò£¬¶øµ÷ÓÃlist.stream().sorted() Ôò»á¸´ÖÆÒ»·ÝÊý¾Ý½øÐвÙ×÷£¬±£³ÖÔÊý¾Ý²»±ä¡£Äã¿ÉÒÔÔÚÕâÀï»ñµÃ¸ü¶à¹ØÓÚAPIÊý¾ÝÁ÷µÄÐÅÏ¢
ÒÔÏÂÊDZÊÕß´ÓJava 8ÎĵµÖÐÕª³öµÄcollectionsºÍstreamsÖ®¼äµÄ±È½Ï¡£Ç¿ÁÒ½¨Òé´ó¼ÒÔĶÁ ÍêÕû°æ¡£
StreamsºÍcollectionsÓÐÒÔϼ¸µãÇø±ð£º
1. ÎÞ´æ´¢¡£steam ²»ÊÇ´æ´¢Êý¾ÝÔªËØµÄÊý¾Ý½á¹¹¡£¶øÊÇͨ¹ý¼ÆËã²Ù×÷¹ÜµÀ´ÓÔ´Í·´«ÊäÊý¾ÝÔªËØ¡£
2.±¾ÖÊÊǺ¯Êý¡£¶ÔStream¶ÔÏó²Ù×÷Äܵõ½Ò»¸ö½á¹û£¬µ«ÊDz»»áÐÞ¸ÄÔʼÊý¾Ý¡£
3. Laziness-seeking£¨ÑÓ³ÙËÑË÷£©£ºStreamµÄºÜ¶à²Ù×÷Èçfilter¡¢map¡¢sortºÍduplicate removal(È¥ÖØ£©¿ÉÒÔÑÓ³ÙʵÏÖ£¬Òâ˼ÊÇÎÒÃÇÖ»Òª¼ì²éµ½Âú×ãÒªÇóµÄÔªËØ¾Í¿ÉÒÔ·µ»Ø¡£
4. ¿ÉÄÜÊDz»ÊÜÏÞÖÆµÄ£ºStreamsÔÊÐíClientÈ¡×ã¹»¶àµÄÔªËØÖ±µ½Âú×ãij¸öÌõ¼þΪֹ¡£¶øCollections²»ÄÜÕâô×ö¡£
5. ÏûºÄµÄ¡£SteamÖеÄÔªËØÔÚsteamÉú´æÆÚÄÚÖ»Äܱ»·ÃÎÊÒ»´Î¡£
Java ºÍ Scala ¶¼¿ÉÒԺܼòµ¥µØÍ¬Ê±¼ÆËã collection ÖеÄÖµ¡£ÔÚ Java ÖУ¬ÄãÖ»Ðèµ÷ÓÃparallelStream()* »òÕß stream().parallel()£¬¶ø²»ÊÇstream()¡£ÔÚ Scala ÖУ¬ÔÚµ÷ÓÃÆäËû·½·¨Ö®Ç°£¬±ØÐëÏȵ÷Óà par()º¯Êý¡£¶øÇÒ¿ÉÒÔͨ¹ýÌí¼ÓparallelismÀ´Ìá¸ß³ÌÐòµÄÐÔÄÜ¡£²»ÐÒµÄÊÇ£¬´ó¶àÊýʱ¼äËüµÄÖ´ÐÐËٶȶ¼·Ç³£Âý¡£ÊÂʵÉÏ£¬parallelismÊÇÒ»¸öºÜÈÝÒ×±»ÎóÓõŦÄÜ¡£
ÔÚ JavaDoc ÖУ¬ parallelStream()·½·¨µÄ½éÉÜÊÇ£º¿ÉÄÜ·µ»ØÒ»¸ö²¢ÐеÄstream£¨collection×÷ΪÊý¾ÝÔ´£©£¬ËùÒÔËüÒ²¿ÉÄÜ·µ»ØÒ»¸ö´®ÐÐ stream¡££¨ ÓÐÈË×ö¹ý¹ØÓÚ¸ÃAPIµÄÑо¿£©
ͼÏñ±êÌâ
Java µÄ Stream API ÊÇÑÓºóÖ´Ðеġ£ÕâÒâζ×Å£¬Ã»ÓÐÖ¸¶¨Ò»¸öÖÕ½á²Ù×÷£¨±ÈÈç collect() ·½·¨µ÷Óã©£¬ÄÇôËùÓеÄÖмäµ÷Ó㨱ÈÈç filter µ÷Óã©ÊDz»»á±»Ö´Ðеġ£ÑÓ³ÙµÄÁ÷´¦ÀíÖ÷ÒªÊÇΪÁËÓÅ»¯stream API µÄÖ´ÐÐЧÂÊ¡£±ÈÈç¶ÔÒ»¸öÊý¾ÝÁ÷½øÐйýÂË¡¢Ó³ÉäÒÔ¼°ÇóºÍÔËË㣬ͨ¹ýʹÓÃÑÓºó»úÖÆ£¬ÄÇôËùÓвÙ×÷Ö»Òª±éÀúÒ»´Î£¬´Ó¶ø¼õÉÙÖмäµ÷Óá£Í¬Ê±£¬ÑÓºóÖ´ÐÐÔÊÐíÿ¸ö²Ù×÷Ö»´¦Àí±ØÒªµÄÊý¾Ý¡£Ïà·´£¬ScalaµÄcollectionsÊǼ´Ê±´¦ÀíµÄ¡£ÕâÑùÊÇ·ñÒâζ×Å£¬ÔÚ²âÊÔÖУ¬Java Stream APIʼÖÕÓÅÓÚ Scala £¿Èç¹ûÖ»±È½ÏJavaµÄ Stream API ºÍ ScalaµÄCollection API£¬ÄÇôJava Stream API µÄÈ·ÓÅÓÚ Scala Collection API¡£µ«ÔÚ Scala ÖÐÓиü¶àµÄÑ¡Ôñ¡£Í¨¹ý¼òµ¥µØµ÷ÓÃtoStream()£¬¾Í¿ÉÒÔ½«Ò»¸ö Collection ת»»³ÉÒ»¸öStream£¬»òÕß¿ÉÒÔʹÓà view £¨Ò»ÖÖÌṩÑÓºó´¦ÀíÄÜÁ¦µÄCollection£©À´´¦ÀíÊý¾Ý¼¯ºÏ¡£
ÏÂÃæ´ÖÂÔ½éÉÜÏÂScalaµÄStreamºÍViewÌØÐÔ
ScalaµÄStream
ScalaµÄStreamºÍJavaµÄÓÐËù²»Í¬¡£ÔÚScala StreamÖУ¬ÎÞÐèµ÷ÓÃÖÕ½á²Ù×÷ȥȡµÃStreamµÄ½á¹û¡£StreamÊÇÒ»¸ö¼Ì³Ð Abstractseq¡¢ LinearseqºÍ GenericTraversableTemplate traitµÄ³éÏóÀà¡£ËùÒÔ£¬Äã¿ÉÒÔ°ÑStreamµ±×÷ SEQ¡£
Èç¹ûÄã²»ÊìϤScala£¬¿ÉÒÔ½«Seqµ±×÷JavaÀïµÄList¡££¨Scala ÖÐµÄ List ²»ÊÇÒ»¸ö½Ó¿Ú£©¡£
ÕâÀïÐèÖªµÀStreams ÖеÄÔªËØ¶¼ÊÇÑÓ³Ù¼ÆËãµÄ£¬ÕýÒòΪ´Ë£¬StreamÄܹ»¼ÆËãÎÞÏÞÊý¾ÝÁ÷¡£Èç¹ûÒª¼ÆË㼯ºÏÖеÄËùÓÐÔªËØ£¬StreamºÍListÓÐÏàͬµÄÐÔÄÜ¡£Ò»µ©¼ÆËã³ö½á¹û£¬ÊýÖµ½«±»»º´æ¡£StreamÓÐÒ»¸öforceº¯Êý£¬Äܹ»Ç¿ÖÆÆÀ¹ÀstreamÔÙ·µ»Ø½á¹û¡£×¢Ò⣬²»ÒªÔÚÎÞÏÞÁ÷Öе÷Óøú¯Êý£¬Ò²²»ÒªÇ¿ÖƸÃAPI´¦ÀíÕû¸östreamµÄ²Ù×÷£¬±ÈÈçsize()¡¢tolist()¡¢foreach()µÈ£¬ÕâЩ²Ù×÷ÔÚScalaµÄStreamÖж¼ÊÇÒþʽµÄ¡£
ÔÚScala StreamÖÐʵÏÖFibonacciÊýÁС£
def fibFrom(a: Int, b: Int): Stream[Int] = a #:: fibFrom(b, a + b) val fib1 = fibFrom(0, 1) //0 1 1 2 3 5 8 ¡ val fib5 = fibFrom(0, 5) //0 5 5 10 15 ¡ //fib1.force //Don¡¯t do this cause it will call the function infinitely and soon you will get the OutOfMemoryError //fib1.size //Don¡¯t do this too with the same reason as above. fib1.take(10) //Do this. It will take the first 10 from the inifite Stream. fib1.take(20).foreach(println(_)) //Prints 20 first numbers |
:: ÊÇcollectionÖг£ÓõÄÁ¬½ÓÊý¾ÝµÄ·½·¨¡£¶ø #:: ±íʾÊÇÁ¬½ÓÊý¾Ýµ«ÊÇÊÇÑÓ³ÙÖ´Ðеģ¨ScalaÖеķ½·¨Ãû¶¼ºÜËæÒ⣩¡£
ScalaµÄView
ÔÙ´ÎÖØÉ꣬ScalaµÄcollectionÊÇÒ»¸öÑϸñcollection£¬¶øviewÊÇ·ÇÑϸñµÄ¡£View ÊÇ»ùÓÚÒ»¸ö»ù´¡ collection µÄ collection£¬ÆäÖÐËùÓеÄת»»¶¼»áÑÓ³ÙÖ´ÐС£Í¨¹ýµ÷Óà view º¯Êý¿ÉÒÔ½«Ñϸñcollectionת»»³É view£¬Ò²¿ÉÒÔͨ¹ýµ÷Óà force ·½·¨×ª»»»ØÀ´¡£View ²¢²»»º´æ½á¹û£¬Ã¿´Îµ÷ÓÃʱ²Å»áÖ´ÐÐת»»¡£¾ÍÏñÊý¾Ý¿âµÄ View£¬µ«ËüÊÇÐéÄâcollection¡£
´´½¨Ò»¸öÊý¾Ý¼¯¡£
public class Pet { public static enum Type { CAT, DOG } public static enum Color { BLACK, WHITE, BROWN, GREEN } private String name; private Type type; private LocalDate birthdate; private Color color; private int weight; ... } |
¼ÙÉèÓÐÒ»¸ö³èÎO£¬½ÓÏÂÀ´»áÀûÓøü¯ºÏÏêϸ˵Ã÷¡£
¹ýÂËÆ÷
ÒªÇ󣺴Ӽ¯ºÏ¹ýÂËÒ»Ö»ÅÖºõºõµÄ³èÎÅÖºõºõµÄ¶¨ÒåÊÇÌåÖØ³¬¹ý50°õ£¬»¹ÏëµÃµ½Ò»¸öÔÚ2013Äê1ÔÂ1ÈÕ³öÉúµÄ³èÎïÃûµ¥¡£ÏÂÃæµÄ´úÂëÆ¬¶ÎÏÔʾÁËÈçºÎÒÔ²»Í¬µÄ·½Ê½ÊµÏÖ¸ÃÂ˲¨Æ÷µÄ¹¤×÷¡£
Java ·½·¨1£º´«Í³·½Ê½
//Before Java 8 List<Pet> tmpList = new ArrayList<>(); for(Pet pet: pets){ if(pet.getBirthdate().isBefore(LocalDate.of(2013, Month.JANUARY, 1)) && pet.getWeight() > 50){ tmpList.add(pet); } } |
ÕâÖÖ·½Ê½ÔÚÃüÁîʽÓïÑÔÖÐÊ®·Ö³£¼û¡£Ê×ÏÈ£¬±ØÐë´´½¨Ò»¸öÁÙʱ¼¯ºÏ£¬È»ºó±éÀúËùÓÐÔªËØ£¬´æ´¢Âú×ãÌõ¼þµÄÔªËØµ½ÁÙʱ¼¯ÖС£µÄÈ·ÓеãÈÆ¿Ú£¬µ«Æä½á¹ûºÍЧÂʶ¼·Ç³£²»´í¡£µ«±¾È˲»µÃ²»É¨Ð˵ØËµ£¬´«Í³·½·¨±ÈStreams API¸ü¿ì¡£²»¹ý£¬ÍêÈ«²»Óõ£ÐÄÐÔÄÜÎÊÌ⣬ÒòΪ´úÂëµÄ¼ò½à±ÈÇá΢µÄÐÔÄÜÔöÒæ¸üÖØÒª¡£
Java ·½·¨2£ºStreams API
//Java 8 - Stream pets.stream() .filter(pet -> pet.getBirthdate().isBefore(LocalDate.of(2013, Month.JANUARY, 1))) .filter(pet -> pet.getWeight() > 50) .collect(toList()) |
ÒÔÉÏ´úÂë±íʾ£¬Ê¹ÓÃStreams API¹ýÂ˼¯ºÏÖеÄÔªËØ¡£Ö®ËùÒÔ¹ÊÒâÁ½´Îµ÷ÓùýÂ˺¯Êý£¬ÊÇÏë±íÃ÷Streams µÄ API Éè¼Æ¾ÍÏñÒ»¸ö Builder pattern¡£ÔÚBuilder patternµ÷Óù¹½¨·½·¨Ö®Ç°£¬¿ÉÒÔ½«¸÷ÖÖ·½·¨´®ÁªÆðÀ´¡£ÔÚStreams APIÖУ¬¹¹½¨·½·¨±»³ÆÎªÖÕ½á²Ù×÷£¬·ÇÖÕ½á²Ù×÷µÄ½Ð×öÖмä²Ù×÷¡£ÖÕ½á²Ù×÷¿ÉÄܲ»Í¬ÓÚ¹¹Ô캯Êý£¬ÒòΪËüÔÚ Streams API ÖÐÖ»Äܱ»µ÷ÓÃÒ»´Î¡£µ«»¹Óкܶà¿ÉʹÓõÄÖÕ½á²Ù×÷£¬±ÈÈçcollect¡¢count¡¢min¡¢max¡¢iterator¡¢toArray¡£ÕâЩ²Ù×÷»á²úÉú½á¹û£¬¶øÖն˲Ù×÷»áÏûºÄÖµ£¬ÀýÈçforEach¡£ÄÇô£¬ÄãÈÏΪ´«Í³·½·¨ºÍ Streams API ÄÄÒ»¸öµÄ¿É¶ÁÐÔ¸üÇ¿£¿
Java ·½·¨3£ºCollections API
//Java 8 - Collection pets.removeIf(pet -> !(pet.getBirthdate().isBefore(LocalDate.of(2013, Month.JANUARY, 1)) && pet.getWeight() > 50)); //Applying De-Morgan's law. pets.removeIf(pet -> pets.get(0).getBirthdate().toEpochDay() >= LocalDate.of(2013, Month.JANUARY, 1).toEpochDay() || pet.getWeight() <= 50); |
ÕâÖÖ·½·¨ÊÇ×î¼ò¶ÌµÄ¡£µ«ÊÇ£¬ËüÐÞ¸ÄÁËÔʼ¼¯ºÏ£¬¶øÇ°ÃæµÄ·½·¨²»»á¡£removeifº¯Êý½«Predicate<T>£¨º¯Êý½Ó¿Ú£©×÷Ϊ²ÎÊý¡£PredicateÊÇÒ»¸öÐÐΪ²ÎÊý£¬ËüÖ»ÓÐÒ»¸öÃûΪtest³éÏó·½·¨£¬Ö»ÐèÒªÒ»¸ö¶ÔÏó²¢·µ»Ø²¼¶ûÖµ¡£×¢Ò⣬ÕâÀï±ØÐëʹÓá°£¡¡±È¡·´£¬»òÕß¿ÉÒÔÓ¦ÓÃDe Morgan¶¨Àí£¬Ê¹µÃ´úÂë¿´ÆðÀ´Ïñ¶þ´ÎÉùÃ÷¡£
Scala·½·¨£ºCollection¡¢ViewºÍStream
//Scala - strict collection pets.filter { pet => pet.getBirthdate.isBefore(LocalDate.of(2013, Month.JANUARY, 1))} .filter { pet => pet.getWeight > 50 } //List[Pet] //Scala - non-strict collection pets.views.filter { pet => pet.getBirthdate.isBefore(LocalDate.of(2013, Month.JANUARY, 1))} .filter { pet => pet.getWeight > 50 } //SeqView[Pet] //Scala - stream pets.toStream.filter { pet => pet.getBirthdate.isBefore(LocalDate.of(2013, Month.JANUARY, 1))} .filter { pet => pet.getWeight > 50 } //Stream[Pet] |
Scala µÄ½â¾ö·½°¸ÀàËÆÓÚJava µÄStreams API¡£µ«Ê×ÏÈ£¬±ØÐëµ÷ÓÃviewº¯Êý°ÑÑϸñ¼¯×ªÏò·ÇÑϸñ¼¯£¬È»ºóÔÙÓÃtostreamº¯Êý°ÑÑϸñ¼¯×ª³ÉÒ»¸östream¡£
½ÓÏÂÀ´Ö±½ÓÉÏ´úÂë¡£
·Ö×é
ͨ¹ýÔªËØµÄÒ»¸öÊôÐÔ¶ÔÆðËùÔÚ¼¯ºÏ×ögroup¡£½á¹ûÊÇMap<T, List<T>>£¬ÆäÖÐTÊÇÒ»¸ö·ºÐÍÀàÐÍ¡£
ÒªÇó£ºÍ¨¹ýÀàÐͶԳèÎï·Ö×飬ÖîÈç¹·£¬Ã¨µÈµÈ¡£

×¢Ò⣺groupingByÊÇjava.util.stream.CollectorsµÄ¾²Ì¬µÄhelper method¡£
ÅÅÐò
¸ù¾ÝÊôÐÔ¶Ô¼¯ºÏÖеÄÔªËØÅÅÐò¡£½á¹û»áÊÇÈκÎÀàÐ͵ļ¯ºÏ£¬¸ù¾ÝÅäÖÃÀ´Î¬³ÖÔªËØË³Ðò¡£
ÒªÇó£ºÐè°´ÕÕÀàÐÍ¡¢Ãû×ÖºÍÑÕÉ«ÅÅÐò¡£

Ó³Éä
½«¸ø¶¨º¯ÊýÓ¦ÓÃÔÚ¼¯ºÏÔªËØÖС£¸ù¾Ý¶¨ÒåµÄº¯Êý²»Í¬£¬Æä·µ»ØµÄ½á¹ûÀàÐÍÒ²²»Í¬¡£
ÒªÇó£ºÐ轫³èÎïת»¯³É×Ö·û´®£¬ÒÔ¡°%s¡ªname: %s, color: %s¡±µÄ¸ñʽ¡£

ѰÕÒµÚÒ»¸ö
·µ»ØµÚÒ»¸öÄÜÓëÖ¸¶¨predicateÆ¥ÅäµÄÖµ¡£
ÒªÇó£ºÕÒÒ»¸öÃûΪ¡°Handsome¡±µÄ³èÎï¡£ÎÞÂÛÓжàÉÙ¸ö¡°Handsome"£¬Ö»È¡µÚÒ»¸ö¡£
Õâ¸öÎÊÌâÓе㼬ÊÖ¡£²»ÖªµÀÄãÊÇ·ñ×¢Ò⣬ÔÚ Scala ÖбÊÕßËùʹÓõÄÊÇ findº¯Êý¶ø²»ÊÇ filter £¿Èç¹ûÓà filter ´úÌæ find£¬Ëü¾Í»á¼ÆË㼯ºÏÖÐËùÓÐÔªËØ£¬ÒòΪ scala collectionÊÇÑϸñµÄ¡£µ«ÊÇ£¬ÔÚ Java µÄ Streams API ÖÐÄã¿ÉÒÔ·ÅÐÄʹÓà filter£¬ÒòΪËü»á¼ÆËãÐèÒªµÄµÚÒ»¸öÖµ£¬²¢²»»á¼ÆËãËùÓÐÔªËØ¡£Õâ¾ÍÊÇÑÓ³ÙÖ´Ðеĺô¦!
½ÓÏÂÀ´£¬Ïò´ó¼Ò½éÉÜ scala Öиü¶à¼¯ºÏÑÓ³ÙÖ´ÐеÄʵÀý¡£ÎÒÃǼٶ¨ filter ×ÜÊÇ·µ»Ø true£¬È»ºóÔÙÈ¡µÚ¶þ¸öÖµ¡£½«»áÊÇʲô½á¹ûÄØ£¿
pets.filter { x => println(x.getName); true }.get(1) --- (1) |
pets.toStream.filter { x => println(x.getName); true }.get(1) -- (2) |
ÈçÉÏËùʾ£¬£¨1£©Ê½½«»á´òÓ¡³ö¼¯ºÏÖÐËùÓгèÎïµÄÃû×Ö£¬¶ø£¨2£©Ê½ÔòÖ»Êä³öǰ2¸ö³èÎïµÄÃû×Ö¡£Õâ¾ÍÊÇlazy collectionµÄºÃ´¦£¬×ÜÊÇÑÓ³Ù¼ÆËã¡£
pets.view.filter { x => println(x.getName); true }.get(1) --- (3) |
£¨3£©Ê½ºÍ£¨2£©Ê½»áÓÐÒ»ÑùµÄ½á¹ûÂð£¿´í£¡ËüµÄ½á¹ûºÍ£¨1£©ÊÇÒ»ÑùµÄ£¬ÄãÖªµÀΪʲôÂð£¿
ͨ¹ý±È½Ï Java ºÍ Scala ÖеÄһЩ¹²Í¬µÄ²Ù×÷·½·¨ ¡ª¡ªfilter¡¢group¡¢map ºÍ find£»ºÜÃ÷ÏÔ Scala µÄ·½·¨±È Java ¸ü¼ò½à¡£Äã¸üϲ»¶ÄÄÒ»¸öÄØ?ÄÄÒ»¸öµÄ¿É¶ÁÐÔ¸üÇ¿£¿
ÔÚÎÄÕµÄÏÂÒ»¸ö²¿·Ö£¬ÎÒÃǽ«±È½ÏÄÄÖÖ·½Ê½¸ü¿ì¡£¾´ÇëÆÚ´ý£¡
|