我正在计算按属性分组的统计信息。对于此属性的每个类别(以String
s给出),我得到了我想要聚合的值。
为此,我需要一个从类别到DescriptiveStatistics
的地图(由org.apache.commons.math.stat.descriptive
提供)。在此地图中,我必须检查对于给定类别是否已创建相应的DescriptiveStatistics
。 此检查以及新DescriptiveStatistics
的创建应由地图完成。
我测试了Apache的LazyMap
,但是非一般性导致我去了Guava的LoadingCache
。这些方面的东西对我有用:
LoadingCache<String, DescriptiveStatistics> groupedStats =
CacheBuilder.newBuilder()
.build(new CacheLoader<String, DescriptiveStatistics>() {
@Override
public DescriptiveStatistics load(String key) {
return new DescriptiveStatistics();
}
});
是否有一个“罗嗦”的解决方案?一个不需要我为了实例化对象而抛出一个匿名类?
答案 0 :(得分:4)
您的原始代码正是Guava团队希望您编写的代码。
我们倾向于避免反思(当然,除了com.google.common.reflect
)。它往往是脆弱的,并且失去了编译时检查的好处 - 如果一个特定的类没有拥有一个公共的无参数构造函数,而你使用clazz.newInstance()
,你就不会' t发现直到运行时。编写直接实现可能会花费你一两行,但我们认为它的好处是值得的。
答案 1 :(得分:0)
我想要更少的罗嗦解决方案创建一个用于缓存的类。
因为有人设计API并不总是让每个人都开心。番石榴缓存非常灵活且适应性强。另外几行代码应该不是问题。
答案 2 :(得分:0)
这是我在减少用户代码中的冗余的想法:一个类Creator<T>
,它正如它所说的那样。
LoadingCache<String, SummaryStatistics> groupedStats =
CacheBuilder.newBuilder().build(
CacheLoader.from(Creators.of(SummaryStatistics.class)));
我想知道这样的野兽是否存在;我在实现Supplier<T>
的类中找不到它。这是一个可能的实现,所有类都在同一个包中:
import com.google.common.base.Supplier;
public class Creator<T> implements Supplier<T> {
private Class<T> class1;
Creator(Class<T> class1) {
this.class1 = class1;
}
@Override
public T get() {
try {
return class1.newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Cannot instantiate object of type "
+ class1.getCanonicalName(),
e);
}
}
}
public class Creators {
public static <T> Creator<T> of(Class<T> class1) {
return new Creator<T>(class1);
}
}
当然,这可以推广到使用带参数的构造函数。