题
我写了一个小的LINQ像的谷歌集合 顶DSL p>
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);
我担心这种做法是否会引起迷你对象的爆炸,并导致一些垃圾收集问题(或任何其他问题)?
解决方案
我相信谷歌集合使用延迟执行其大部分的迭代器。延迟执行将最小化创建为它将消除中间对象的数量最可能为每个呼叫被创建的中间/临时列表(其中,排序依据等)。
基本上,不计算由currentlyAssigned.iterator()返回的每个元素,直到调用iterator.next()。在此之前,你currentlyAssigned迭代仅仅是一组操作的,仅此而已。
您对微型物体的爆炸唯一关心的,如果这些对象持续超过一个单一的元素操作的持续时间更长......峰值内存使用量可以得到在这种情况下,相当大的,你可能会非常大耗尽内存列表或者如果你的对象转换(即在所有的字符串或东西调用ToUpper的())。这将仅是这种情况,如果在哪里()是另一个清单,其结果然后的OrderBy()创建的另一个列表,等等等等。
至于GC处理许多短命的对象,没有任何问题。现代Java垃圾收集大量优化来处理确切行为。
其他提示
我认为这取决于如何改变的行为,如果它像一个懒惰的过滤器,即你不重视每个结果的参考。那么它超过OK对象明智计数。垃圾收集明智的,你不保留任何隐藏的引用,一旦你失去了根参考全图不可达,被收集。路要走的人,这是很整洁。
在垃圾收集器具有用于短期对象特殊的代码,它们是非常非常便宜使用。基本上偶尔所有可达年轻对象被标记和所有其他对象被一举回收。
不隶属于 StackOverflow