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);
我担心这种方法是否会导致迷你对象爆炸并导致一些垃圾收集问题(或任何其他问题)?
答案 0 :(得分:3)
我相信Google Collections会对其大多数迭代器使用延迟执行。延迟执行将最小化创建的中间对象的数量,因为它将消除可为每个调用创建的大多数中间/临时列表(where,orderby等)。
基本上,在调用iterator.next()之前,不会计算currentAssigned.iterator()返回的每个元素。在此之前,您的currentAssigned iterable只是一组操作,仅此而已。
如果这些对象的持续时间超过单个元素操作的持续时间,那么你对迷你对象爆炸的唯一关注......在这种情况下,峰值内存使用量会变得非常大,你可能会在非常大的情况下耗尽内存列表或者您是否正在转换对象(即在所有字符串或其他内容上调用ToUpper())。只有当where()的结果是另一个列表,然后orderby()创建另一个列表时,才会出现这种情况,依此类推。
就GC处理许多短寿命物体而言,没有问题。现代Java垃圾收集器经过大量优化,可以处理这种确切的行为。
答案 1 :(得分:1)
我认为这取决于变换的行为方式,如果它像一个惰性过滤器,即你没有附加对每个结果的引用。然后它比OK对象更明智。明智的垃圾收集,你没有保留任何隐藏的引用,一旦你失去根引用,整个图形变得无法访问并被收集。去男人的方式这真的很整洁。
答案 2 :(得分:0)
垃圾收集器具有短期对象的特殊代码,使用起来非常便宜。基本上偶尔会标记所有可到达的年轻对象,并且一举夺回所有其他对象。