Jcat
宠辱不惊,闲看庭前花开花落~~
posts - 173,comments - 67,trackbacks - 0

1. 闭包代表(定义)了一段代码(操作):光看这一句,其实方法也能实现相同的功能呀。
2. 闭包可以作为方法的参数:这才是闭包的特殊之处和真正意义。


下面演示一个只有闭包能做,方法做不到的例子。

方法的作用是提炼共性,再代之以不同的参数。即对不同的“数据”进行相同的“操作”。从3个loop可以看出:
    Comm1:相同的数据
    Comm2:相同的for循环
    Diff1:循环体内执行的操作不同

Comm1很好搞定,参数aa就是提炼出的共性
Comm2看似是共性,却很难提炼,因为for循环和循环体内的操作实际是一个整体;Comm2被Diff1纠缠,3个loop是完全不同的3组操作,无法提炼。

比如,如果现在想要按照奇数循环,只能依次改动三个循环。 

int [] aa  =  [ 1 2 3 4 5 6 ]

//  loop1
for  ( int  i  =   0 ; i  <  aa.length; i ++ ) {
    println aa[i]
}

//  loop2
for  ( int  i  =   0 ; i  <  aa.length; i ++ ) {
    print aa[i]
}

//  loop3
for  ( int  i  =   0 ; i  <  aa.length; i ++ ) {
    print aa[i] 
+   '   '
}
        

//  loop1
for  ( int  i  =   0 ; i  <  aa.length;  +=   2 ) {
    println aa[i]
}

//  loop2
for  ( int  i  =   0 ; i  <  aa.length;  +=   2 ) {
    print aa[i]
}

//  loop3
for  ( int  i  =   0 ; i  <  aa.length;  +=   2 ) {
    print aa[i] 
+   '   '
}


下面我们看看闭包的强大之处,Comm1和Comm2都被很好的封装在了loop方法里;Diff1则作为参数(闭包)传入loop方法。

static void main(String[] a) {
    
int[] aa = [123456]

    loop(aa) { println it }
    loop(aa) { print it }   
    loop(aa) { print it 
+ ' ' }
}
如果我们想要改变循环的方式,只需要改一处
static void loop(int[] aa, Closure c) {
    
for (int i = 0; i < aa.length; i++) {
        c.call(aa[i])
    }
    println 
' '
}
static void loop(int[] aa, Closure c) {
    
for (int i = 0; i < aa.length; += 2) {
        c.call(aa[i])
    }
    println 
' '
}

总结,闭包本身并没什么难点,关键是怎样合理的设计一个接受Closure类型参数的方法。从GDK的方法也可以看出,大多数接受闭包的方法都是和数组迭代有关(也即循环)。
posted on 2008-11-07 02:04 Jcat 阅读(1535) 评论(2)  编辑  收藏 所属分类: Java

FeedBack:
# re: Groovy Closure “操作”也成了参数[未登录]
2008-11-07 20:11 | 咖啡
这个很熟悉. 好像有其他哪个语言类似的.   回复  更多评论
  
# re: Groovy Closure “操作”也成了参数
2008-11-07 21:37 | Jcat
很多动态语言都有,如Ruby。Groovy正是借鉴了其它动态语言,将闭包引入了Java。另外,现在也正在讨论,是否要在JDK7中加入闭包。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: