我用Java编写了一些代码,我需要将代码转换为Groovy,以利用Groovy提供的优势。有没有办法将Java代码自动转换为Groovy,或者某些现有的插件可以让我从这个方向开始?
答案 0 :(得分:5)
我想用一个示例程序来展示它:
private static List<List> subn(int n, List li) {
List<List> ret = new ArrayList<List>();
if (n == 0) {
ret.add(new ArrayList());
return ret;
}
if (li.isEmpty()) {
return ret;
}
T x = li.get(0);
List xs = li.subList(1, li.size());
for (List sub : subn(n-1, xs)) {
sub.add(0, x);
ret.add(sub);
}
ret.addAll(subn(n, xs));
return ret;
}
对于第一步,我想删除静态类型,虽然我不是很谨慎但是对于这么小的代码,我会去做它。
def subn(n, li) {
def ret = new ArrayList();
if (n == 0) {
ret.add(new ArrayList());
return ret;
}
if (li.isEmpty()) {
return ret;
}
def x = li.get(0);
def xs = li.subList(1, li.size());
for (sub in subn(n-1, xs)) {
sub.add(0, x);
ret.add(sub);
}
ret.addAll(subn(n, xs));
return ret;
}
这将改变字符数:)但不改变结构。 现在让我们改变数组文字:
def subn(n, li) {
def ret = [];
if (n == 0) {
ret.add([]);
return ret;
}
if (li.isEmpty()) {
return ret;
}
def x = li.get(0);
def xs = li.subList(1, li.size());
for (sub in subn(n-1, xs)) {
sub.add(0, x);
ret.add(sub);
}
ret.addAll(subn(n, xs));
return ret;
}
我们看到更多的字符被修剪,现在让我们改变if语句。
def subn(n, li) {
if (n == 0) return [[]];
if (li.isEmpty()) return [];
def ret = [];
def x = li.get(0);
def xs = li.subList(1, li.size());
for (sub in subn(n-1, xs)) {
sub.add(0, x);
ret.add(sub);
}
ret.addAll(subn(n, xs));
return ret;
}
我不是真正的短变量名的粉丝所以下一步是重命名一些变量。除此之外,我将略微更改循环以使用每个函数。 'it'魔术变量取代了'sub'变量。
def subn(n, list) {
if (n == 0) return [[]];
if (list.isEmpty()) return [];
def ret = [];
def head = list.get(0);
def remainder = list.subList(1, list.size());
subn(n-1, remainder).each {
it.add(0, head);
ret.add(it);
}
ret.addAll(subn(n, remainder));
return ret;
}
通过将集合添加到一起,我们可以更简化循环:
def subn(n, list) {
if (n == 0) return [[]];
if (list.isEmpty()) return [];
def ret = [];
def head = list.get(0);
def remainder = list.subList(1, list.size());
subn(n-1, remainder).each {
ret.add([head] + it);
}
ret.addAll(subn(n, remainder));
return ret;
}
看一下代码,很明显'ret'变量只是在积累结果。我们可以为此目的使用collect方法。
def subn(n, list) {
if (n == 0) return [[]];
if (list.isEmpty()) return [];
def head = list.get(0);
def remainder = list.subList(1, list.size());
def ret = subn(n-1, remainder).collect { [head] + it }
ret.addAll(subn(n, remainder));
return ret;
}
事实上,如果只是将两个集合添加到一起,我们根本不需要'ret':
def subn(n, list) {
if (n == 0) return [[]];
if (list.isEmpty()) return [];
def head = list.get(0);
def remainder = list.subList(1, list.size());
return subn(n-1, remainder).collect { [head] + it } + subn(n, remainder);
}
最后让内联head变量。它只在一个地方使用,所以不值得保留它。此外,我们将使用Groovy列表索引来删除get()调用。
def subn(n, list) {
if (n == 0) return [[]];
if (list.isEmpty()) return [];
def remainder = list.subList(1, list.size());
return subn(n-1, remainder).collect { [list[ 0 ]] + it } + subn(n, remainder);
}
答案 1 :(得分:5)
有趣的事实 - Groovy已经有了一个工具,称为java2groovy
- 您可以在Groovy安装的bin
目录中看到它。它是一个在发行版中调用类的包装脚本 - org.codehaus.groovy.antlr.java.Java2GroovyMain
。
不要注意添加到转换代码标题中的警告:
!! NOT FIT FOR ANY PURPOSE !!
和
'java2groovy' cannot be used to convert one working program into another
更严重的是 - 我非常确定代码在很长一段时间内没有更新,而且它的高峰期功能不是很丰富。
我的建议与其他人所说的相似 - 如果它正在工作和测试,请保留原样。如果你确实需要它在Groovy中,那么Groovy和Java之间存在一些问题上的差异,主要是因为Groovy使用{}字符作为闭包;需要转换使用那些(例如数组)的Java构造。另外,奇怪的是 - 在Groovy中没有do
/ while
循环。并且有些情况下运行时行为与编译时不同,但Java使用编译的内容。动态调度通常会产生更好的选择,因为Groovy会查看 类型的内容,而不是它们在编译时看到的内容。但如果您期望它是相同的,那么问题就更好了。
有关问题的说明和一些解决方法,请参阅http://groovy.codehaus.org/Differences+from+Java。
答案 2 :(得分:0)
我推荐这个!值得一读。 它对我有用!有点简单。