Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Guava MapMaker是否为factory方法选择设置最大尺寸(0)?_Java_Guava - Fatal编程技术网

Java Guava MapMaker是否为factory方法选择设置最大尺寸(0)?

Java Guava MapMaker是否为factory方法选择设置最大尺寸(0)?,java,guava,Java,Guava,我正在使用MapMaker在我的应用程序中实现数据对象的缓存: public class DataObjectCache<DO extends MyDataObject> { private final ConcurrentMap<String, DO> innerCache; public DataObjectCache(Class<DO> doClass) { Function<String, DO> lo

我正在使用MapMaker在我的应用程序中实现数据对象的缓存:

public class DataObjectCache<DO extends MyDataObject> {

    private final ConcurrentMap<String, DO> innerCache;

    public DataObjectCache(Class<DO> doClass) {

        Function<String, DO> loadFunction = new Function<String, DO>() {
            @Override
            public DO apply(String id) {
                //load and return DO instance
            }
        };

        innerCache = new MapMaker()
             .softValues()
             .makeComputingMap(loadFunction);
    }

    private DO getDataObject(String id) {
        return innerCache.get(id);
    }

    private void putDataObject(DO dataObject) {
        innerCache.putIfAbsent(dataObject.getID(), dataObject);
    }
}
公共类DataObjectCache{
私有最终ConcurrentMap内部缓存;
公共DataObjectCache(类doClass){
函数loadFunction=新函数(){
@凌驾
公用DO应用(字符串id){
//加载并返回DO实例
}
};
innerCache=new MapMaker()
.softValues()
.makeComputingMap(加载函数);
}
私有DO getDataObject(字符串id){
返回innerCache.get(id);
}
私有void putDataObject(DO dataObject){
innerCache.putIfAbsent(dataObject.getID(),dataObject);
}
}
将为每个数据对象类实例化其中一个DataObjectCache,并将它们保存在主地图中,使用类对象作为键

我不希望缓存少数数据对象类的实例。但是,我仍然希望它们由函数调用的相同代码实例化,并且在加载它们时仍然需要并发性

在这些情况下,我想知道是否可以将映射的最大大小设置为0,以便立即逐出条目,但仍然可以利用映射的原子计算特性。这是个好主意吗?效率低下

编辑:


我意识到,如果在加载条目后立即将其逐出,则无法保证它们被明确加载-如果地图没有跟踪它们,则具有相同ID的对象的多个实例可能会在环境中浮动。因此,我不想这样做,我想我会对我不想占用缓存的对象类型使用弱值而不是软值-让我知道是否有人对此有意见。

好吧,
MapMaker.maximumSize
有一行:
检查参数(size>0,“最大大小必须为正”)
,这将使这不可能。
expireAfter
方法也需要正参数。很明显,API设计师不希望您使用他们的
MapMaker
-以这种方式制作地图


也就是说,我想,如果您真的想使用缓存作为传递,您可以使用1纳秒的
expireAfterWrite
。这是一种黑客行为,但实际上也会有同样的效果。

根据您的编辑,听起来您正在寻找的是一名实习生。interner返回一个代表性实例;根据
equals
方法,对于所有相等的对象,
Interner.intern
将返回相同的对象。从Javadoc:

选择并返回代表 实例的任何一个集合 每个实例都相等的实例 其他的。如果给定两个相等的输入 对于此方法,两个调用都将返回 同样的例子。就是, 实习生(a)。等于(a)始终有效,并且 实习生(a)==实习生(b)当且仅当 a、 等于(b)。请注意,实习生(a)是 现在允许返回一个实例 如果 最初被拘留的实例是 垃圾收集

看到和

也就是说,这取决于你说你不想缓存它是什么意思。如果您确实希望每次都返回一个新实例,那么您必须有多个等效对象的实例“四处浮动”

Interning保留一个实例(因此它可以返回相同的实例),所以它仍然是一种缓存。我想知道为什么要避免缓存。如果是因为对象的大小,可以使用弱interner;当不再引用该实例时,它将可用于GC。同样,简单地使用带有弱值的
MapMaker
map也可以实现这一点


另一方面,如果你不想缓存的原因是你的数据容易更改,那么实习可能是你的答案。我可以想象你想要的是每次检索对象,然后对其进行实习。如果对象与缓存的对象相等,则interner将只返回现有实例。如果是不同的,实习生会缓存新的。然后,您的责任是在您的对象上编写一个
equals
方法,以满足使用新vs interned实例的要求。

实际上,这一点在09版中有所更改,现在被专门称为您可以做的事情:“当大小为零时,可以将元素成功添加到地图中,但会立即逐出。“是的,我看到这一点后考虑过这种方法。但我意识到它不符合我的要求,请看我上面的编辑。哦,这很有趣。因此,如果我理解正确,您建议我对不希望缓存的数据对象类型使用Interner(映射仍将用于缓存类型)。我猜这将是一个软弱的实习生,对吗?我在我的答案中添加了一些内容,试图回应你的评论。让我知道如果你需要更多的澄清来帮助我解决这个问题。你说得对,实习生是一种缓存。当我说我不想缓存某些类型的对象时,我的意思是,我知道这些对象通常是一次性使用的,并且在引用它们之前再保留它们没有任何意义。我想我会坚持所有类型的映射,只使用弱值而不是软值。谢谢你教我关于实习生+1的知识