0

我在Google Collections之上写了一个类似于 DSL 的 Linq

    public class IterableQuery {

   public static <T> Where<T> from(Iterable<T> originalCollection) {
      return  new Where<T>( Iterables.transform(originalCollection, IterableQuery.<T>SAME()));
   }

   private static <T> Function<T, T> SAME() {
      return new Function<T, T>(){
         public T apply(T arg0) {
            return arg0;
         }
      };
   }


   public static class SelectOrderBy<T>{

      private final Iterable<T> iterable;

      public SelectOrderBy(Iterable<T> iteable) {
         this.iterable = iteable;
      }

      public  SelectOrderBy<T> orderyBy( Comparator<T> sort ){
          Ordering.forComparator(sort).sort((List< ? extends T>) iterable);
          return new SelectOrderBy<T>( iterable);
      }

      public  <F> Iterable<F> select(  Function<? super T,? extends F> function){
         return Iterables.transform(iterable, function);
      }
      public  Iterable<T> selectEveryThing( ){
         return iterable;
      }
   }


   public static class Where<T>{

      private final Iterable<T> iterable;

      public Where(Iterable<T> iterable) {
         this.iterable = iterable;
      }

      public    SelectOrderBy<T> where(Predicate<T> predicate) {
         return  new SelectOrderBy<T>( Iterables.filter(iterable, predicate));
      }
   }

}

所以我可以以更简洁易读的方式进行查询集合

 Iterable<? extends NewOrder > currentlyAssigned = 
         IterableQuery.
          from(orders).
          where(placedInLast10Days).
          orderBy(lastName). 
          select(orderToNewOrder);

我担心这种方法是否会导致迷你对象爆炸并导致一些垃圾收集问题(或任何其他问题)?

4

3 回答 3

3

我相信 Google Collections 的大多数迭代器都使用延迟执行。延迟执行将最小化创建的中间对象的数量,因为它将消除可以为每个调用(where、orderby 等)创建的大多数中间/临时列表。

基本上,在调用 iterator.next() 之前,不会计算 currentAssigned.iterator() 返回的每个元素。在那之前,您的 currentAssigned 迭代只是一组操作,仅此而已。

如果这些对象的持续时间超过单个元素操作的持续时间,您唯一关心的就是迷你对象的爆炸......在这种情况下,峰值内存使用量可能会变得非常大,并且您可能会在非常大的列表上耗尽内存,或者如果您正在转换对象(即在所有字符串或其他东西上调用 ToUpper() )。仅当 where() 的结果是另一个列表时才会出现这种情况,然后 orderby() 创建了另一个列表,依此类推。

就 GC 处理许多短期对象而言,没有问题。现代 Java 垃圾收集器经过大量优化以处理该确切行为。

于 2009-04-13T18:45:26.173 回答
1

我认为这取决于变换的行为方式,如果它像一个惰性过滤器,即你不附加对每个结果的引用。那么它的数量超过了OK对象。垃圾收集明智,您不会保留任何隐藏的引用,一旦您丢失了根引用,整个图将变得无法访问并被收集。走的路,这真的很整洁。

于 2009-04-13T18:05:32.353 回答
0

垃圾收集器有专门的短寿命对象代码,使用起来非常便宜。基本上偶尔会标记所有可到达的年轻对象,然后一举回收所有其他对象。

于 2009-04-15T09:51:38.733 回答