|
ÕªÒª£ºËäÈ»JavaÉîµÃ´óÁ¿¿ª·¢Õßϲ°®£¬µ«ÊÇ¶Ô±ÈÆäËûÏÖ´ú±à³ÌÓïÑÔ£¬ÆäÓ﷨ȷʵÂÔÏÔÈß³¤¡£µ«ÊÇͨ¹ýJava8£¬Ö±½ÓÀûÓÃlambda±í´ïʽ¾ÍÄܱàд³ö¼È¿É¶ÁÓÖ¼ò½àµÄ´úÂë¡£

¡¾±àÕß°´¡¿±¾ÎÄ×÷ÕßHussachai PuripunpinyoµÄÈí¼þ¹¤³Ìʦ£¬×÷Õßͨ¹ý¶Ô±ÈJava 8ºÍScala£¬¶ÔÐÔÄܺͱí´ï·½ÃæµÄ²îÒì½øÐÐÁË·ÖÎö£¬²¢ÇÒÉîÈëÌÖÂÛ¹ØÓÚStream APIµÄÇø±ð£¬ÓÉOneAPM¹¤³Ìʦ·Òë¡£
ÒÔÏÂΪÒëÎÄ
ÊýÄêµÈ´ý£¬Java 8ÖÕÓÚÌí¼ÓÁ˸߽׺¯ÊýÕâ¸öÌØÐÔ¡£±¾È˺Üϲ»¶Java£¬µ«²»µÃ²»³ÐÈÏ£¬Ïà±ÈÆäËûÏÖ´ú±à³ÌÓïÑÔ£¬JavaÓï·¨·Ç³£Èß³¤¡£È»¶øÍ¨¹ýJava8£¬Ö±½ÓÀûÓÃlambda±í´ïʽ¾ÍÄܱàд³ö¼È¿É¶ÁÓÖ¼ò½àµÄ´úÂ루ÓÐʱÉõÖÁ±È´«Í³·½·¨¸ü¾ß¿É¶ÁÐÔ£©¡£
Java 8ÓÚ2014Äê3ÔÂ3ÈÕ·¢²¼£¬µ«±ÊÕß×î½ü²ÅÓлú»á½Ó´¥¡£ÒòΪ±ÊÕßÒ²ºÜÊìϤScala£¬ËùÒԾͲúÉúÁ˶ԱÈJava 8ºÍScalaÔÚ±í´ïÐÔºÍÐÔÄÜ·½ÃæµÄ²îÒ죬±È½Ï½«Î§ÈÆStream APIÕ¹¿ª£¬Í¬Ê±Ò²»á½éÉÜÈçºÎʹÓÃStream APIÀ´²Ù×÷¼¯ºÏ¡£
ÓÉÓÚÎÄÕÂÌ«³¤£¬ËùÒÔ·ÖÒÔÏÂÈý¸ö²¿·ÖÏêϸÐðÊö¡£
Part 1.Lambda±í´ïʽ
Part 2.Stream API vs Scala collection API
Part 3.Trust no one, bench everything(ÒýÓÃ×Ôsbt-jmh)
Ê×ÏÈ£¬ÎÒÃÇÀ´Á˽âÏÂJava 8µÄlambda±í´ïʽ£¬ËäÈ»²»ÖªµÀ¼´Ê¹±í´ïʽ²¿·ÖÊÇ¿ÉÌæ´úµÄ£¬ËûÃÇÈ´³ÆÖ®Îªlambda±í´ïʽ¡£ÕâÀïÍêÈ«¿ÉÒÔÓÃÉùÃ÷À´´úÌæ±í´ïʽ£¬È»ºó˵Java 8»¹Ö§³ÖlambdaÉùÃ÷¡£±à³ÌÓïÑÔ½«º¯Êý×÷ΪһµÈ¹«Ãñ£¬º¯Êý¿ÉÒÔ±»×÷Ϊ²ÎÊý»òÕß·µ»ØÖµ´«µÝ£¬ÒòΪËü±»ÊÓΪ¶ÔÏó¡£JavaÊÇÒ»ÖÖ¾²Ì¬µÄÇ¿ÀàÐÍÓïÑÔ¡£ËùÒÔ£¬º¯Êý±ØÐëÓÐÀàÐÍ£¬Òò´ËËüÒ²ÊÇÒ»¸ö½Ó¿Ú¡£
ÁíÒ»·½Ã棬lambda º¯Êý¾ÍÊÇʵÏÖÁ˺¯Êý½Ó¿ÚµÄÒ»¸öÀà¡£ÎÞÐè´´½¨Õâ¸öº¯ÊýµÄÀ࣬±àÒëÆ÷»áÖ±½ÓʵÏÖ¡£²»ÐÒµÄÊÇ£¬JavaûÓÐ ScalaÄÇÑù¸ß¼¶µÄÀàÐͽӿڡ£Èç¹ûÄãÏëÉùÃ÷Ò»¸ölambda±í´ïʽ£¬¾Í±ØÐëÖ¸¶¨Ä¿±êÀàÐÍ¡£Êµ¼ÊÉÏ£¬ÓÉÓÚJava±ØÐë±£³ÖÏòºó¼æÈÝÐÔ£¬ÕâÒ²ÊÇ¿ÉÀí½âµÄ£¬¶øÇÒ¾ÍĿǰÀ´ËµJavaÍê³ÉµÃºÜºÃ¡£ÀýÈ磬Thread.stop() ÔÚJDK 1.0°æÊ±·¢²¼£¬ÒѹýʱÁËÊ®¶àÄ꣬µ«¼´±ãµ½½ñÌìÈÔÈ»»¹ÔÚʹÓá£ËùÒÔ£¬²»ÒªÒòΪÓïÑÔXYZµÄÓï·¨£¨»ò·½·¨£©¸üºÃ£¬¾ÍÖ¸ÍûJava´Ó¸ù±¾ÉϸıäÓï·¨½á¹¹¡£
ËùÒÔ£¬Java 8µÄÓïÑÔÉè¼ÆÊ¦ÃÇÆæË¼ÃîÏ룬×ö³Éº¯Êý½Ó¿Ú£¡º¯Êý½Ó¿ÚÊÇÖ»ÓÐÒ»¸ö³éÏó·½·¨µÄ½Ó¿Ú¡£ÒªÖªµÀ£¬´ó¶àÊý»Øµ÷½Ó¿ÚÒѾÂú×ãÕâÒ»ÒªÇó¡£Òò´Ë£¬ÎÒÃÇ¿ÉÒÔ²»×öÈκÎÐÞ¸ÄÖØÓÃÕâЩ½Ó¿Ú¡£@FunctionalInterfaceÊDZíʾÒÑ×¢ÊͽӿÚÊǺ¯Êý½Ó¿ÚµÄ×¢ÊÍ¡£´Ë×¢ÊÍÊÇ¿ÉÑ¡µÄ£¬³ý·ÇÓмì²éÒªÇ󣬷ñÔò²»ÓÃÔÙ½øÐд¦Àí¡£
Çë¼Çס£¬lambda±í´ïʽ±ØÐ붨ÒåÀàÐÍ£¬¶ø¸ÃÀàÐͱØÐëÖ»ÓÐÒ»¸ö³éÏó·½·¨¡£
//Before Java 8 Runnable r = new Runnable(){ public void run(){ System.out.println(¡°This should be run in another thread¡±); } }; |
//Java 8 Runnable r = () -> System.out.println(¡°This should be run in another thread¡±); |
Èç¹ûÒ»¸öº¯ÊýÓÐÒ»¸ö»ò¶à¸ö²ÎÊý²¢ÇÒÓзµ»ØÖµÄØ£¿ÎªÁ˽â¾öÕâ¸öÎÊÌ⣬Java 8ÌṩÁËһϵÁÐͨÓú¯Êý½Ó¿Ú£¬ÔÚjava.util.function°üÀï¡£
//Java 8 Function<String, Integer> parseInt = (String s) -> Integer.parseInt(s); |
¸Ã²ÎÊýÀàÐÍ¿ÉÒÔ´Óº¯ÊýÖÐÍÆ¶Ï£¬¾ÍÏñJava7ÖеÄdiamond operator£¬ËùÒÔ¿ÉÒÔÊ¡ÂÔ¡£ÎÒÃÇ¿ÉÒÔÖØÐ´¸Ãº¯Êý£¬ÈçÏÂËùʾ£º
//Java 8 Function<String, Integer> parseInt = s -> Integer.parseInt(s); |
Èç¹ûÒ»¸öº¯ÊýÓÐÁ½¸ö²ÎÊýÄØ£¿ÎÞÐèµ£ÐÄ£¬Java 8 ÖÐÓÐ BiFunction¡£
//Java 8 BiFunction<Integer, Integer, Integer> multiplier = (i1, i2) -> i1 * i2; //you can¡¯t omit parenthesis here! |
Èç¹ûÒ»¸öº¯Êý½Ó¿ÚÓÐÈý¸ö²ÎÊýÄØ£¿TriFunction£¿ÓïÑÔÉè¼ÆÕßÖ¹²½ÓÚBiFunction¡£·ñÔò£¬¿ÉÄÜÕæ»áÓÐTriFunction¡¢quadfunction¡¢pentfunctionµÈ¡£½âÊÍһϣ¬±ÊÕßÊDzÉÓÃIUPAC¹æÔòÀ´ÃüÃûº¯ÊýµÄ¡£È»ºó£¬¿ÉÒÔ°´ÈçÏÂËùʾ¶¨ÒåTriFunction¡£
//Java 8 @FunctionalInterface interface TriFunction<A, B, C, R> { public R apply(A a, B b, C c); } |
È»ºóµ¼Èë½Ó¿Ú£¬²¢°ÑËüµ±×÷lambda±í´ïʽÀàÐÍʹÓá£
//Java 8 TriFunction<Integer, Integer, Integer, Integer> sumOfThree = (i1, i2, i3) -> i1 + i2 + i3; |
ÕâÀïÄãÓ¦¸ÃÄÜÀí½âΪʲôÉè¼ÆÕßÖ¹²½ÓÚBiFunction¡£
Èç¹û»¹Ã»Ã÷°×£¬²»·Á¿´¿´PentFunction£¬¼ÙÉèÎÒÃÇÔÚÆäËûµØ·½ÒѾ¶¨ÒåÁËPentFunction¡£
//Java 8 PentFunction<Integer, Integer, Integer, Integer, Integer, Integer> sumOfFive = (i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5; |
ÄãÖªµÀEnnfunctionÊǶ೤Â𣿣¨À¶¡ÓïÖУ¬enn ±íʾ9£©Äã±ØÐëÉ걨10ÖÖÀàÐÍ£¨Ç°9¸öÊDzÎÊý£¬×îºóÒ»¸öÊÇ·µ»ØÀàÐÍ£©£¬´ó¸ÅÕûÐж¼Ö»ÓÐÀàÐÍÁË¡£ÄÇôÉùÃ÷Ò»¸öÀàÐÍÊÇ·ñÓбØÒªÄØ£¿´ð°¸Êǿ϶¨µÄ¡££¨ÕâÒ²ÊÇΪʲô±ÊÕßÈÏΪScalaµÄÀàÐͽӿڱÈJavaµÄ¸üºÃ£©
ScalaÒ²ÓÐÆälambda±í´ïʽÀàÐÍ¡£ÔÚScalaÖУ¬Äã¿ÉÒÔ´´½¨ÓÐ22¸ö²ÎÊýµÄlambda±í´ïʽ£¬Òâζ×ÅScalaÓÐÿ¸öº¯ÊýµÄÀàÐÍ£¨Function0¡¢Function1¡¢¡¡Function22£©¡£º¯ÊýÀàÐÍÔÚScalaº¯ÊýÖÐÊÇÒ»¸öTrait£¬Trait¾ÍÏñ JavaÖеijéÏóÀ࣬µ«¿ÉÒÔµ±×ö»ìºÏÀàÐÍʹÓá£Èç¹û»¹ÐèÒª22¸öÒÔÉϵIJÎÊý£¬ÄÇ´ó¸ÅÊÇÄ㺯ÊýµÄÉè¼ÆÓÐÎÊÌâ¡£±ØÐëÒª¿¼ÂÇËù´«µÝµÄÒ»×é²ÎÊýµÄÀàÐÍ¡£ÔÚ´Ë£¬±ÊÕß½«²»ÔÙ׸Êö¹ØÓÚLambda±í´ïʽµÄϸ½Ú¡£
ÏÂÃæÀ´¿´¿´ScalaµÄÆäËûÄÚÈÝ¡£ScalaÒ²ÊÇÀàËÆJavaµÄ¾²Ì¬Ç¿ÀàÐÍÓïÑÔ£¬µ«ËüÒ»¿ªÊ¼¾ÍÊǺ¯ÊýÓïÑÔ¡£Òò´Ë£¬ËüÄܺܺõØÈÚºÏÃæÏò¶ÔÏóºÍº¯Êý±à³Ì¡£ÓÉÓÚScalaºÍJavaËù²ÉÓõķ½·¨²»Í¬£¬ÕâÀï²»Äܸø³öRunnableµÄScalaʵÀý¡£ScalaÓÐ×Ô¼º½â¾öÎÊÌâµÄ·½·¨£¬ËùÒÔ½ÓÏÂÀ´»áÏêϸ̽ÌÖ¡£
//Scala Future(println{¡°This should be run in another thread¡±}) |
ÓëÒÔÏÂJava8 µÄ´úÂëµÈЧ¡£
//Java 8 //assume that you have instantiated ExecutorService beforehand. Runnable r = () -> System.out.println(¡°This should be run in another thread¡±); executorService.submit(r); |
Èç¹ûÄãÏëÉùÃ÷Ò»¸ölambda±í´ïʽ£¬¿ÉÒÔ²»ÓÃÏñJavaÄÇÑùÉùÃ÷Ò»¸öÏÔʽÀàÐÍ¡£
//Java 8 Function<String, Integer> parseInt = s -> Integer.parseInt(s); |
//Scala val parseInt = (s: String) => s.toInt //or val parseInt:String => Int = s => s.toInt //or val parseInt:Function1[String, Int] = s => s.toInt |
ËùÒÔ£¬ÔÚScalaÖеÄÈ·ÓжàÖÖ°ì·¨À´ÉùÃ÷ÀàÐÍ¡£ÈñàÒëÆ÷À´Ö´ÐС£ÄÇôPentFunctionÄØ£¿
//Java 8 PentFunction<Integer, Integer, Integer, Integer, Integer, Integer> sumOfFive = (i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5; |
//Scala val sumOfFive = (i1: Int, i2: Int, i3: Int, i4: Int, i5: Int) => i1 + i2 + i3 + i4 + i5; |
Scala¸ü¶Ì£¬ÒòΪ²»ÐèÒªÉùÃ÷½Ó¿ÚÀàÐÍ£¬¶øÕûÊýÀàÐÍÔÚScalaÖÐÊÇint¡£¶Ì²»×ÜÒâζןüºÃ¡£ScalaµÄ·½·¨¸üºÃ£¬²»ÊÇÒòΪ¶Ì£¬¶øÊÇÒòΪ¸ü¾ß¿É¶ÁÐÔ¡£ÀàÐ͵ÄÉÏÏÂÎÄÔÚ²ÎÊýÁбíÖУ¬¿ÉÒԺܿìÕÒ³ö²ÎÊýÀàÐÍ¡£Èç¹û»¹²»È·¶¨£¬¿ÉÒÔÔٲο¼ÒÔÏ´úÂë¡£
//Java 8 PentFunction<String, Integer, Double, Boolean, String, String> sumOfFive = (i1, i2, i3, i4, i5) -> i1 + i2 + i3 + i4 + i5; |
//Scala val sumOfFive = (i1: String, i2: Int, i3: Double, i4: Boolean, i5: String) => i1 + i2 + i3 + i4 + i5; |
ÔÚScalaÖУ¬¿ÉÒÔºÜÃ÷È·µØËµ³öi3ÀàÐÍÊÇDoubleÐÍ£¬µ«ÔÚJava 8ÖУ¬»¹ÐèÒªËãËãËüÊÇʲôÀàÐÍ¡£Äã¿ÉÄÜÕù±ç˵JavaÒ²¿ÉÒÔ£¬µ«³öÏÖÕâÑùµÄ×´¿ö£º
//Java 8 PentFunction<Integer, String, Integer, Double, Boolean, String> sumOfFive = (Integer i1, String i2, Integer i3, Double i4, Boolean i5) -> i1 + i2 + i3 + i4 + i5; |
Äã±ØÐëÒ»±éÓÖÒ»±éµÄÖØ¸´ÏÂÈ¥¡£
³ý´ËÖ®Í⣬Java8²¢Ã»ÓÐPentFunction£¬ÐèÒª×Ô¼º¶¨Òå¡£
//Java 8 @FunctionalInterface interface PentFunction<A, B, C, D, E, R> { public R apply(A a, B b, C c, D d, E e); } |
ÊDz»ÊÇÒâζ×ÅScala¾Í¸üºÃÄØ£¿ÔÚijЩ·½ÃæµÄÈ·ÊÇ¡£µ«Ò²ÓÐºÜ¶àµØ·½Scala²»ÈçJava¡£ËùÒÔºÜÄÑ˵µ½µ×ÄÄÖÖ¸üºÃ£¬ÎÒÖ®ËùÒÔ¶ÔÁ½Õß½øÐбȽϣ¬ÊÇÒòΪScalaÊÇÒ»ÖÖº¯ÊýÓïÑÔ£¬¶øJava 8Ö§³ÖһЩº¯ÊýÌØµã£¬ËùÒÔµÃÕÒº¯ÊýÓïÑÔÀ´±È½Ï¡£ÓÉÓÚScala¿ÉÒÔÔËÐÐÔÚJVMÉÏ£¬ÓÃËüÀ´¶Ô±ÈÔٺò»¹ý¡£¿ÉÄÜÄã»áÔÚʹÓú¯Êýʱ£¬ScalaÓиü¼ò½àµÄÓï·¨ºÍ·½·¨£¬ÕâÊÇÒòΪËü±¾À´¾ÍÊǺ¯ÊýÓïÑÔ£¬¶øJavaµÄÉè¼ÆÕßÔÚ²»ÆÆ»µÖ®Ç°µÄ»ù´¡ÉÏÍØÕ¹Éè¼Æ£¬ÏÔÈ»»áÓиü¶àÏÞÖÆ¡£
¾¡¹ÜJavaÔÚÓï·¨ÉÏÓëlambda±í´ïʽÏà±ÈÓÐÒ»¶¨¾ÖÏÞÐÔ£¬µ«Java8 Ò²Òý½øÁËһЩºÜ¿áµÄ¹¦ÄÜ¡£ÀýÈ磬ÀûÓ÷½·¨ÒýÓõÄÌØÐÔͨ¹ýÖØÓÃÏÖÓз½·¨Ê¹µÃ±àдlambda±í´ïʽ¸ü¼ò½à¡£¸ü¼ò½àÂ𣿣¿£¿
//Java 8 Function<String, Integer> parseInt = s -> Integer.parseInt(s); |
¿ÉÒÔʹÓ÷½·¨ÒýÓÃÀ´ÖØÐ´º¯Êý£¬ÈçÏÂËùʾ
//Java 8 Function<String, Integer> parseInt = Integer::parseInt; |
»¹¿ÉÒÔͨ¹ýʵÀý·½·¨À´Ê¹Ó÷½·¨ÒýÓá£Ö®ºó»áÔÚµÚ¶þ²¿·ÖµÄStream APIÖÐÖ¸³öÕâÖÖ·½·¨µÄ¿ÉÓÃÐÔ¡£
·½·¨ÒýÓõĹ¹Ôì¹æÔò
1.(args) -> ClassName.staticMethod(args);
¿ÉÒÔÏñÕâÑùÖØÐ´ClassName::staticMethod;
Function<Integer, String> intToStr = String::valueOf; |
2.(instance, args) -> instance.instanceMethod(args);
¿ÉÒÔÏñÕâÑùÖØÐ´ClassName::instanceMethod£»
BiFunction<String,String, Integer> indexOf = String::indexOf; |
3.(args) -> expression.instanceMethod(args);
¿ÉÒÔÏñÕâÑùÖØÐ´expression::instanceMethod£»
Function<String, Integer>indexOf = new String()::indexOf; |
ÄãÓÐûÓÐ×¢Òâµ½¹æÔò2ÓÐµãÆæ¹Ö£¿Óеã»ìÂÒ£¿¾¡¹ÜindexOfº¯ÊýÖ»ÐèÒª1¸ö²ÎÊý£¬µ«BiFunctionµÄÄ¿±êÀàÐÍÊÇÐèÒª2¸ö²ÎÊý¡£Æäʵ£¬ÕâÖÖÓ÷¨Í¨³£ÔÚStream APIÖÐʹÓ㬵±¿´²»µ½ÀàÐÍÃûʱ²ÅÓÐÒâÒå¡£
pets.stream().map(Pet::getName).collect(toList()); // The signature of map() function can be derived as // <String> Stream<String> map(Function<? super Pet, ? extends String> mapper) |
´Ó¹æÔò3ÖУ¬Äã¿ÉÄÜ»áºÃÆæÄÜ·ñÓà lambda ±í´ïÊ½Ìæ»» new String()£¿
Äã¿ÉÒÔÓÃÕâÖÖ·½·¨¹¹ÔìÒ»¸ö¶ÔÏó
Supplier<String> str =String::new; |
ÄÇô¿ÉÒÔÕâÑù×öÂð£¿
Function<Supplier<String>,Integer> indexOf = (String::new)::indexOf; |
²»ÄÜ¡£Ëü²»ÄܱàÒ룬±àÒëÆ÷»áÌáʾ¡°The target type of this expression must be a functional interface¡±¡£´íÎóÐÅÏ¢ºÜÈÝÒ×ÒýÆðÎó½â£¬¶øÇÒËÆºõJava 8ͨ¹ý·ºÐͲÎÊý²¢²»Ö§³ÖÀàÐͽӿڡ£¼´Ê¹Ê¹ÓÃÒ»¸öFunctionalinterfaceµÄʵÀý£¨ÈçÇ°ÃæÌáµ½µÄ¡°STR¡±£©£¬Ò²»á³öÏÖÁíÒ»¸ö´íÎó¡°The type Supplier<String> does not define indexOf(Supplier<String>) that is applicable here¡±¡£String::newµÄº¯Êý½Ó¿ÚÊÇSupplier<String>£¬¶øÇÒËüÖ»Óз½·¨ÃüÃûΪget()¡£indexOfÊÇÒ»¸öÊôÓÚString¶ÔÏóµÄʵÀý·½·¨¡£Òò´Ë£¬±ØÐëÖØÐ´Õâ¶Î´úÂ룬ÈçÏÂËùʾ¡£
//Java Function<String, Integer> indexOf = ((Supplier<String>)String::new).get()::indexOf; |
Java 8 ÊÇ·ñÖ§³Öcurrying (partial function)£¿
µÄÈ·¿ÉÐУ¬µ«Äã²»ÄÜʹÓ÷½·¨ÒýÓá£Äã¿ÉÒÔÈÏΪÊÇÒ»¸öpartialº¯Êý£¬µ«ÊÇËü·µ»ØµÄÊǺ¯Êý¶ø²»Êǽá¹û¡£½Ó׎«Òª½éÉÜʹÓÃcurryingµÄ¼òµ¥ÊµÀý£¬µ«Õâ¸öÀý×ÓÒ²¿ÉÄÜÐв»Í¨¡£ÔÚ´«µÝµ½º¯Êý֮ǰ£¬ÎÒÃÇͨ³£½øÐвÎÊý´¦Àí¡£µ«ÎÞÂÛÈçºÎ£¬ÏÈ¿´¿´ÈçºÎÀûÓÃlambda±í´ïʽʵÏÖpartial º¯Êý¡£¼ÙÉèÄãÐèÒªÀûÓÃcurryingʵÏÖÁ½¸öÕûÊýÏà¼ÓµÄº¯Êý¡£
//Java IntFunction<IntUnaryOperator>add = a -> b -> a + b; add.apply(2).applyAsInt(3);//the result is 4! I'm kidding it's 5. |
¸Ãº¯Êý¿ÉÒÔͬʱ²ÉÓÃÁ½¸ö²ÎÊý¡£
//Java Supplier<BiFunction<Integer,Integer, Integer>> add = () -> (a, b) -> a + b; add.get().apply(2, 3); |
ÏÖÔÚ£¬¿ÉÒÔ¿´¿´Scala·½·¨¡£
//Scala val add = (a: Int) => (b:Int) => a + b add(1)(2) |
//Scala val add = () => (a: Int,b: Int) => a + b add2()(1,2) |
ÒòΪÀàÐÍÒýÓúÍÓï·¨ÌÇ£¬ScalaµÄ·½·¨±ÈJava¸ü¼ò¶Ì¡£ÔÚScalaÖУ¬Äã²»ÐèÒªÔÚFunction traitÉϵ÷ÓÃapply ·½·¨£¬±àÒëÆ÷»á¼´Ê±µØ½«()ת»»Îªapply ·½·¨¡£
|