0

作为 groovy 的新手...

我正在尝试替换事件侦听器、过滤器等的 java 习惯用法。

我在 groovy 中的工作代码如下:

def find() {
    ODB odb = ODBFactory.open(files.nodupes); // data nucleus object database
    Objects<Prospect> src = odb.getObjects(new QProspect());

    src.each { println it };

    odb.close();

}

class QProspect extends SimpleNativeQuery {
    public boolean match(Prospect p) {
        if (p.url) {
            return p.url.endsWith(".biz");
        }
        return false;
    }
}

现在,这与我在 java 中的习惯相去甚远,其中 Query 接口的实现是在 odb.getObjects() 方法中完成的。如果我在哪里编写“java”代码,我可能会执行以下操作,但它不起作用:

Objects<Prospect> src = odb.getObjects( {
        boolean match(p) { 
            if (p.url) {
            return p.url.endsWith(".biz");
        }
            return false; 
        }
    } as SimpleNativeQuery);

或者更好,我希望它是这样的:

 Objects<Prospect> src = odb.getObjects( 
      { it.url.endsWith(".biz") } as SimpleNativeQuery
 );

但是,将“匹配”方法与外部脚本上下文相关联并让我失望的是什么groovy。

我发现 groovy... groovy 反正我会坚持学习更多。谢谢。


我应该问的是我们如何在 groovy 中做“匿名”类。这是java的成语:

void defReadAFile() {
    File[] files = new File(".").listFiles(new FileFilter() {
        public boolean accept(File file) {
            return file.getPath().endsWith(".biz");
        }
    });
}

groovy 可以在没有额外的类声明的情况下如此简洁吗?

4

3 回答 3

1

我认为如果您将问题抽象化以使其不依赖于 Neodatis DB 接口,它会帮助您获得答案——这让我陷入了一个循环,因为我从未使用过它。我在下面写的关于它的内容是基于一个非常粗略的分析。

就此而言,我也从未使用过 Groovy,尽管我喜欢我所看到的。但是看到其他人还没有回答,你被我困住了:-)

我认为问题(或至少部分问题)可能是您对 Neodatis 的 SimpleNativeQuery 类期望过高。看起来它甚至在将对象添加到返回的集合之前都没有尝试过滤它们。我认为您想使用org.neodatis.odb.impl.core.query.criteria.CriteriaQuery. (注意包路径中的“impl”。这让我有点紧张,因为我不确定这个类是否是由调用者使用的。但我没有看到 Neodatis 中允许的任何其他类用于指定查询条件。)

但不是直接使用 CriteriaQuery,我认为您宁愿将它包装在 Groovy 类中,以便您可以将它与闭包一起使用。所以,我认为带有闭包的 Groovy 版本的代码可能看起来像这样:

// Create a class that wraps CriteriaQuery and allows you 
// to pass closures.  This is wordy too, but at least it's
// reusable.

import org.neodatis.odb.impl.core.query.criteria;

class GroovyCriteriaQuery extends CriteriaQuery {
    private final c;

    QProspect(theClosure) {
         // I prefer to check for null here, instead of in match()
         if (theClosure == null) {
             throw new InvalidArgumentException("theClosure can't be null!");
         }
         c = theClosure;
    }

    public boolean match(AbstractObjectInfo aoi){
        //!! I'm assuming here that 'aoi' can be used as the actual
        //!! object instance (or at least as proxy for it.)
        //!! (You may have to extract the actual object from aoi before calling c.)
        return c(aoi);
    }
}

// Now use the query class in some random code.

 Objects<Prospect> src = odb.getObjects( 
      new GroovyCriteriaQuery(
          { it.url.endsWith(".biz") } 
      )
 )

我希望这有帮助!

于 2009-04-17T04:01:37.353 回答
1

我相信您真正的问题是“在调用不使用闭包的 Java API 时,我可以使用闭包而不是匿名类吗”。答案是肯定的“是”。这:

 Objects<Prospect> src = odb.getObjects( 
      { it.url.endsWith(".biz") } as SimpleNativeQuery
 );

应该管用。您写“但是,将“匹配”方法与外部脚本上下文相关联并让我失望的是什么 groovy 。它究竟是如何失败的?在我看来,您似乎遇到了一个简单的技术问题来获得既是“常规方式”又是您想要工作的解决方案。

于 2009-04-17T14:00:11.517 回答
0

是的,谢谢大家,它的工作原理。

我还发现了为什么 SimpleNativeQuery 不起作用(根据 Dan Breslau)。

我尝试了以下方法,效果很好。所以这个成语确实按预期工作。

new File("c:\\temp").listFiles({ it.path.endsWith(".html") } as FileFilter);

由于neodatis界面,下一个不起作用。该接口不强制执行 match() 方法!它只在文档中提到它,但它不存在于类文件中:

public class SimpleNativeQuery extends AbstactQuery{

}

Objects<Prospect> src = odb.getObjects( 
  { it.url.endsWith(".biz") } as SimpleNativeQuery
);

在上面,由于 SimpleNativeQuery 没有 match() 方法,因此 groovy 编译器无法识别应该将闭包附加到 SimpleNativeQuery 中的哪个方法;然后它默认为外部 groovy 脚本。

这是我使用 groovy 的第三天,我很喜欢它。

两本书都很棒:- Groovy Recipes (Scott Davis) - Programming Groovy (Venkat Subramaniam)

于 2009-04-17T14:13:13.453 回答