重用缓存的实例

时间:2016-01-03 08:27:00

标签: java caching

我有一个使用数据结构Point的应用程序。假设总共有50个不同的Point实例(意思是p1.equals(p2) == false)。但是在计算期间,会创建新实例的载荷,这实际上与已实例化的对象相同。

存储这些实例时,这会对内存消耗产生严重影响: 50个不同的Point由500个Point个实例表示。在数据结构中,没有任何东西可以阻止已经存在的实例的重用。出于这个原因,我创建了一个缓存:

HashMap<Point, Point> pointCache = new HashMap<>();

所以我可以检查点是否存在,如果不存在则添加它。然而,这种缓存看起来有点过分,因为密钥和值基本相同。

此外,我已经有了一张地图:

HashMap<Point, Boolean> flag = new HashMap<>();

我很好奇的是:是否有一个像我可以用于flag的数据结构的地图,可以检索密钥?如果没有,我可以使用任何其他数据结构作为缓存,更像是一个集合,并允许轻松检查和检索?

编辑:为了完整起见,我使用的Point班级为javafx.geometry.Point2D,因此我无法更改。

3 个答案:

答案 0 :(得分:5)

为了这个答案,我们假设Point的唯一性由两个int坐标x和y确定(你可以很容易地改变它以适应确定的实际参数)您Point的唯一性。

您不想创建Point个实例,以确定某些PointHashSet中是否已存在HashMap。这违背了避免创建多个实例的目的(尽管使用HashMapHashSet会阻止您保留所有这些重复实例,并且GC将很快发布它们,因此它可能足以解决内存消耗问题)。

我建议您在Point getPoint(int x,int y)课程中使用静态Point方法。该方法将在静态内部HashMap<Integer,HashMap<Integer,Point>>内检查这些x,y坐标是否已经具有相应的Point实例并返回该实例。如果某个实例不存在,则会创建该实例并将其添加到HashMap

这类似于Integer.valueOf(int)对小整数的作用 - 它返回一个缓存的Integer实例,而不是创建一个新实例。

答案 1 :(得分:2)

你的地图是完全合理的。如果你愿意,你可以创建自己的包装类,但我现在可能会坚持使用地图。如果Set<E>公开了“获取与此相等的现有条目”的操作,那么您可以使用它,但a)它不会,而b)HashSet构建在{{1}上无论如何。

答案 2 :(得分:1)

最好使用function (r) { console.log (r) }代替HashSet,这可以避免您针对每个点存储不同的HashMap。虽然boolean会在内部使用Set但代替值,但它会使用相同的HashMap引用,这比存储奇怪的50 Object值更好感觉并且在你的情况下毫无用处。

您可以执行以下查找:

boolean