groovy中的reverse()方法只是迭代的抽象吗?

时间:2012-07-25 07:45:42

标签: loops groovy iteration

基于question,用户想要访问100000行文件的第99999行,而不必在前99998行使用eachLine闭包进行迭代。所以,我建议他使用

file.readLines().reverse()[1]访问文件的第99999行。

这对程序员来说具有逻辑吸引力。但是,我对这种方法实施的复杂性非常怀疑。

reverse()方法仅仅是对程序员隐藏的行的完整迭代的抽象,还是真正的智能化,以便能够以尽可能少的行数进行迭代以达到所需的线?

3 个答案:

答案 0 :(得分:2)

正如您可以看到from the codereverse()在Java中调用Collections.reverse来反转列表。

然而,非变异代码为您提供了另一种选择。使用listIterator(),您可以获得一个包含hasPreviousprevious的迭代器,以便返回列表,如果您这样做:

// Our list
def a = [ 1, 2, 3, 4 ]
// Get a list iterator pointing at the end
def listIterator = a.listIterator( a.size() )
// Wrap the previous calls in another iterator
def iter = [ hasNext:{ listIterator.hasPrevious() },
             next:{ listIterator.previous() } ] as Iterator

我们可以这样做:

// Check the value of 1 element from the end of the list
assert iter[ 1 ] == 3

然而,所有这些都是一个封面下的ArrayList,所以如果你这样做,它几乎肯定更快(并且更容易读取代码):

assert a[ 2 ] == 3
而不是所有的逆转。虽然显然,这需要分析以确保我是对的......

答案 1 :(得分:0)

根据“Javadoc”,它只是以相反的顺序创建一个新列表:

除非我遗漏了什么,否则你是正确的,立即跳转光标并不是那么聪明。我的理解是,如果它被索引为一个数组,它可以直接访问它,但如果不是必须全部迭代。


替代方案可能是:

file.readLines().last()[-1]

答案 2 :(得分:0)

这个答案:

def a= [1, 2, 3, 4]
def listIterator= a.listIterator(a.size())
def iter= [hasNext: {listIterator.hasPrevious()},
              next: {listIterator.previous()}] as Iterator
assert iter[1] == 3

仅适用于Groovy-1.7.2及之后。

在Groovy-1.7.1,1.7.0,1.7 beta,1.6,1.5和1.0-RC-01中,它没有找到代理的getAt(1)方法调用。对于版本1.0-RC-06及之前的版本,java.util.HashMap不能转换为java.util.Iterator。