我试图通过以下代码从排序后的地图中获取前K个元素:
//return top rank k elements
public static LinkedHashMap<String,Double> getTopRank(int i){
//store top k elements
LinkedHashMap<String, Double> result=new LinkedHashMap<>();
int count=0;
//use the static rankMap in the class
rankMap.each {key,value->
result.put(key, value);
count++;
if(count>=i){
println "Time to return"
return result;
}
}
//in case the loop does not work
return result;
}
我期望的是,当结果Map已经有i个元素的大小时,该方法将返回,给我一个i-size排序的地图。请注意rankMap
以我想要的特定顺序存储元素,并且它的大小远远大于传递给方法的int。
我正在通过
LinkedHashMap<String,Double> content=getTopRank(outputSize);
但出乎意料的是,最终内容的大小为rankMap
而不是i
!在控制台中,我看到了数百条Time to return
行。行return result
一次又一次地执行,直到它到达rankMap
的末尾。
我非常确定第getTopRank(outputSize)
行不在循环中。然后我觉得奇怪的是为什么这个方法可以多次返回而不会结束。是否由我在关闭时放置return
语句引起的?
请告诉我或告诉我Groovy中的情况如何。更进一步,我怎样才能从排序后的地图中获得前k个元素呢?
答案 0 :(得分:4)
你误解了Groovy的关键概念。
在到达结束之前完成each()
执行的唯一方法是抛出异常。如果您想有条件地退出循环,请使用标准循环类型,例如for
或while
:
int count=0
def result = [:]
for( def e in rankMap ){
count++
result[ e.key ] = e.value
if( i <= count ) return result
}
答案 1 :(得分:2)
方法本身没有返回。 each
是一个接收闭包的方法。闭包有自己的返回上下文,它与调用它们的方法无关,因此,循环不会被破坏。
我想建议从地图entrySet
获取一个范围并收集结果条目:
def getTopRank(int i) {
rankMap
.entrySet()
.toList()[0..<i]
.collectEntries()
}
rankMap = [
'Beatles' : 'The White Album',
'Pink Floyd' : 'The Dark Side of the Moon',
'Rolling Stones' : 'Sticky Fingers',
'The Doors' : 'Morrison Hotel',
'Bob Dylan' : 'Bob Dylan'
]
assert getTopRank(2) == [
'Beatles' : 'The White Album',
'Pink Floyd' : 'The Dark Side of the Moon']
assert getTopRank(4) == [
'Beatles' : 'The White Album',
'Pink Floyd' : 'The Dark Side of the Moon',
'Rolling Stones' : 'Sticky Fingers',
'The Doors' : 'Morrison Hotel',]
答案 2 :(得分:0)
public static LinkedHashMap<String,Double> getTopRank(int i){
rankMap.take(i)
}
http://www.groovy-lang.org/gdk.html
http://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Map.html#take(int)