作为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中进行“匿名”课程。这是java习语:
void defReadAFile() {
File[] files = new File(".").listFiles(new FileFilter() {
public boolean accept(File file) {
return file.getPath().endsWith(".biz");
}
});
}
groovy可以简洁,没有额外的类声明吗?
答案 0 :(得分:1)
我认为如果你提取问题以便它不依赖于Neodatis数据库接口,这会帮助你得到答案 - 这让我陷入了循环,因为我从未使用它。我在下面写的关于它的内容是基于粗略的分析。
就此而言,我从未使用过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") }
)
)
我希望这有帮助!
答案 1 :(得分:1)
我相信你真正的问题是“在调用不使用闭包的Java API时,我可以使用闭包而不是匿名类”。答案肯定是“是”。这样:
Objects<Prospect> src = odb.getObjects(
{ it.url.endsWith(".biz") } as SimpleNativeQuery
);
应该有效。你写了“但是,将”匹配“方法与外部脚本上下文相关联并使我失败的是什么groovy”。它到底是怎么失败的?在我看来,你有一个简单的技术问题,以获得既“时髦的方式”和你想要工作的解决方案。
答案 2 :(得分: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(斯科特戴维斯) - 编程Groovy(Venkat Subramaniam)