0

我正在计算按属性分组的统计数据。对于这个属性的每个类别(以Strings 给出),我得到我想要聚合的值。

为此,我需要一个从类别到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();
            }
        });

有没有更“罗嗦”的解决方案?一个不需要我为了实例化对象而投入匿名类的方法?

4

3 回答 3

4

您的原始代码正是 Guava 团队希望您编写的代码。

我们倾向于避免反思(当然,在 中除外com.google.common.reflect)。它往往很脆弱并且失去了编译时检查的好处——如果一个特定的类没有公共的无参数构造函数,并且你使用clazz.newInstance()了 ,那么直到运行时你才会发现它。编写直接实现可能会花费您一两行代码,但我们认为这样做的好处是值得的。

于 2012-10-27T00:17:14.037 回答
0

我希望少罗嗦的解决方案创建一个用于缓存的类。

作为某人设计 API 不能总是让每个人都开心。Guava 缓存非常灵活且适应性强。并且额外的几行代码应该不是问题。

于 2012-10-26T22:08:36.017 回答
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);
    }
}

当然,这可以推广到使用带参数的构造函数。

于 2012-10-26T22:16:54.963 回答