Groovy探索之闭包 三

                        Groovy探索之闭包 三
 
我们知道,Groovy语言是建立在JVM的基础上的,我们在使用Groovy语言的时候,就迫切希望我们Groovy程序能够运用自如的使用以前的Java API或者以前Java代码的积累。
在JDK中,对内部类的使用是很多的,但Groovy语言是不支持内部类的,我们该怎么办呢?
请看下面的例子:
public class Person {
   
    private String name ;
   
    private int age ;
   
    public Person(String name, int age)
    {
       this . name = name;
       this . age = age;
    }
 
    public int getAge() {
       return age ;
    }
 
    public void setAge( int age) {
       this . age = age;
    }
 
    public String getName() {
       return name ;
    }
 
    public void setName(String name) {
       this . name = name;
    }
 
}
 
这是一个典型的 JavaBean 类,假如我们有了如下的一个关于 Person 对象的 List 对象:
       List list = new ArrayList();
       Person p1 = new Person( "Tom" ,23);
       list.add(p1);
       Person p2 = new Person( "Alice" ,18);
       list.add(p2);
       Person p3 = new Person( "Wallam" ,31);
       list.add(p3);
       Person p4 = new Person( "Rose" ,25);
    list.add(p4);
 
现在的问题是,我们需要对 list 中的 person 对象按 age 属性的大小排序。
我们知道,在 java.util.Collections 中,有一个 sort 方法可以帮我们排序,但该方法要求我们输入一个 Comparator 的实现。如下:
       Collections.sort(list, new Comparator(){
           public int compare(Object node1, Object node2) {
              return ((Person)node1).getAge()-((Person)node2).getAge();
           }
    });
 
有关 Comparator 接口的详细用法,我在这里不详细说明了,如果不清楚可以在网上搜索它的用法。
下面我们来测试排序后的 list 对象:
       for ( int i=0;i<list.size();i++)
       {
           System. out .println(((Person)list.get(i)).getName());
    }
 
结果为:
Alice
Tom
Rose
Wallam
 
以上是Java语言编程的解决方案,但在Groovy语言中不支持如下的一个匿名内部类的解决方案:
new Comparator(){
           public int compare(Object node1, Object node2) {
              return ((Person)node1).getAge()-((Person)node2).getAge();
           }
    }
 
正是这个匿名内部类告诉 sort 方法如何排序的。
既然 Groovy 语言不支持内部类,那么我们该如何使用 Collections.sort 方法呢?答案是闭包。
是的,闭包!
先来看我们的 Domain 对象:
class Person
{
        String name
        int age
}
 
然后生成我们需要测试的 List 对象:
def list = [ new Person(name: 'Tom' ,age: 23 ), new Person(name: 'Alice' ,age: 18 ),
                new Person(name: 'Wallam' ,age: 31 ), new Person(name: 'Rose' ,age: 25 )]
 
然后,我们创建一个闭包,把它声明成Comparator对象:
      def comparatorImpl = {
            node1,node2 ->
             node1.age-node2.age
 } as Comparator
 
可以看到 comparatorImpl 是一个典型的闭包,和其他闭包没有两样。但后面的“ as Comparator ”却把这个闭包声明为一个 Comparator 接口的实现。
下面,我们来使用这个接口的实现:
Collections. sort (list,comparatorImpl)
 
这就完成了排序的过程,最后我们来看看排序的结果:
     list. each {
         println it.name
 }
 
打印结果为:
Alice
Tom
Rose
Wallam
 
是的,我们只需要将一个闭包声明成一个接口的实现类,就可以使用闭包来代替匿名内部类了。一切都是那么的简单明了。
这样的解决方案在你在 Groovy 语言中使用 Java api 的时候会经常碰到,特别是你是使用 Swing 或其他 API GUI 编程的时候,更是会经常碰到。在这样的时刻,别忘了使用闭包来代替匿名内部类。
 
当然,如果不是使用旧的 api ,即使是我们自己写的接口,也可以通过闭包来实现它。为什么在这里还要使用闭包呢?无他,只因为闭包更加方便和灵活。
下面我们来看看一个例子:
interface Test
{
        def test ()
}
 
如果我们使用闭包来实现上面的接口,那么该怎么做呢?
      def test = {
             println 'ok'
     } as Test
     
  test . test ()
 
运行结果为:
ok
 
可以看到,使用闭包的作用和匿名内部类的效果一样,肯定比另写一个类更加的简单。
看到这里,你肯定会问,如果接口里面有多个方法,该怎么使用闭包来实现接口呢?
请看下面的例子:
interface MultiFuncTest
{
        def test1()
        def test2(str)
}
 
Groovy 语言给出的解决方案其实很简单,对于多方法的接口实现,使用 Map 对象来实现,其中, key 为方法名, value 为闭包实现,如下:
      def impl = [test1:{ println 'test' },
                  test2:{str -> println str}] as MultiFuncTest
 
可以看到,这样的实现也是非常简单方便的。
下面来测试一下:
         impl.test1()
      impl.test2( 'ok' )
 
运行结果为:
test
ok
 
这样的解决方案的确非常简单方便,非常的敏捷。但如果你不喜欢这样的是实现,也可以直接创建一个公开类来实现接口。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值