【问题标题】:Groovy .collect with number of elements limitGroovy .collect 元素数量限制
【发布时间】:2011-11-21 18:13:27
【问题描述】:

有没有办法使用 groovy .collect 方法,但只能在源数组中达到某个索引?

例如,如果您的源迭代器长度为 100 万,而您的限制为 100,那么您最终会得到一个包含 100 个项目的数组。

【问题讨论】:

    标签: java grails groovy


    【解决方案1】:

    从 Groovy 1.8.1 开始你也可以这样做

    list.take(100).collect { ... }
    

    其中 take 将返回列表中的前 100 个元素。

    【讨论】:

    • take 是像 Clojure 中的懒惰还是严格?
    • 在没有阅读代码的情况下,我认为 take(...) 是严格的。 Lazy 在像 Clojure 这样数据结构不可变的语言中很棒,而在几乎所有内容都是可变的 Groovy 中则不然。懒惰仍然可以很好,但作为默认设置没有意义。
    • 这是对列表的操作,因此整个列表将在内存中,因此它不会像 clojure 中那样懒惰。
    【解决方案2】:

    如果您正在使用任何实现java.util.List 的数据结构,您可以对其执行collection.subList(0, 100)。其中 0 是开始索引,100 是结束。之后,您会将新集合传递给collect()

    这是一个使用扩展 java.util.Iterator 的对象的示例:

    public class LimitIterator implements Iterator, Iterable {
       private it
       private limit
       private count
    
       LimitIterator(Iterator it, int limit) {
          limit = limit;
          count = 0;
          it = it
       }
    
       boolean hasNext(){
          return (count >= limit) ? false : it.hasNext()
       }
    
       Object next() {
          if (!hasNext()) throw new java.util.NoSuchElementException()
    
          count++
          return it.next()
       }
    
       Iterator iterator(){
          return this;
       }
    
       void remove(){
          throw new UnsupportedOperationException("remove() not supported")
       }
    
    }
    
    // Create a range from 1 to 10000
    // and an empty list.
    def list = 1..10000
    def shortList = []
    
    // Ensure that everything is as expected
    assert list instanceof java.util.List
    assert list.iterator() instanceof java.util.Iterator
    assert list.size() == 10000
    assert shortList instanceof java.util.List
    
    // Grab the first 100 elements out of the lists iterator object.
    for (i in new LimitIterator(list.iterator(), 100)) {
        shortlist.add(i);
    }
    assert shortlist.size() == 100
    

    【讨论】:

    • 不幸的是它不是一个列表
    • @Matt 您可以调用toList()as List 将其转换为列表
    • 我担心最终可能会将整个迭代器读入内存
    • @Matt 数组当前是如何存储的?
    • @Matt 你总是可以创建一个实现迭代器并采用最大尺寸的包装器。
    【解决方案3】:

    您可以使用一系列索引来获取子列表,然后将collect 应用于子列表。

    def result = list[0..100].collect { ... }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-18
      • 2020-10-28
      • 2020-03-21
      • 2020-09-28
      • 2013-04-08
      • 1970-01-01
      相关资源
      最近更新 更多