Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.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 重用缓存实例_Java_Caching - Fatal编程技术网

Java 重用缓存实例

Java 重用缓存实例,java,caching,Java,Caching,我有一个应用程序使用数据结构点。假设总共有50个不同的点实例(意思是p1.equals(p2)==false)。但是,在计算过程中会创建新实例的负载,这些新实例实际上与已实例化的对象相同 由于存储了这些实例,这对内存消耗有很大影响: 50个不同的点由50万个点实例表示。在数据结构中,没有任何东西会阻止重用已经存在的实例。因此,我创建了一个缓存: HashMap<Point, Point> pointCache = new HashMap<>(); HashMap poi

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

由于存储了这些实例,这对内存消耗有很大影响: 50个不同的
由50万个
实例表示。在数据结构中,没有任何东西会阻止重用已经存在的实例。因此,我创建了一个缓存:

HashMap<Point, Point> pointCache = new HashMap<>();
HashMap pointCache=newhashmap();
因此,我可以检查该点是否存在,如果不存在,则添加该点。然而,这种缓存看起来有点过分,因为键和值本质上是相同的

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

HashMap<Point, Boolean> flag = new HashMap<>();
HashMap flag=newhashmap();
我好奇的是:是否有一个类似于地图的数据结构,我可以用于
标志
,允许检索密钥?如果没有的话,是否还有其他数据结构可以用于缓存,它更像一个集合,并且可以方便地进行检查和检索


编辑:为了完整起见,我使用的
类是
javafx.geometry.Point2D
,因此我无法更改任何内容。

您的地图是完全合理的。如果愿意的话,您可以创建自己的包装器类,但我现在可能会坚持使用map。如果
Set
公开了“获取与此项相等的现有项”的操作,则可以使用该操作,但是a)没有,b)
HashSet
无论如何都是建立在
HashMap
上的。

最好使用
HashSet
而不是
HashMap
,这样可以避免对每个点存储不同的
布尔值。虽然
Set
会在内部使用
HashMap
,但它会使用相同的
对象
引用,这比存储奇数的50个
布尔值要好,因为这些值在您的情况下没有意义,也没有用处

您可以执行如下查找:

 if (set.contains(point)) {
    ...
 }

为了得到这个答案,我们假设
的唯一性由两个int坐标x和y确定(您可以轻松更改该坐标,以适合确定
唯一性的实际参数)

您不想创建一个
实例来确定该
是否已经存在于某些
哈希集
哈希映射
中。这违背了避免创建多个实例的目的(尽管使用
HashMap
HashSet
会阻止您保留所有这些重复实例,并且GC将很快释放它们,因此可能足以解决内存消耗问题)

我建议在
Point
类中使用静态
Point-getPoint(intx,inty)
方法。该方法将在静态内部
HashMap
中检查这些x、y坐标是否已经有相应的
实例,并返回该实例。如果一个实例不存在,它将被创建并添加到
HashMap


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

通常这似乎是一个好的解决方案,不幸的是,我的
Point
类是
javafx.geometry.Point2D
,因此我无法更改它。提供我自己的
类是否值得花费开销?@hotzst您仍然可以使用
点2d
类,而无需包装它。只需创建一个
Point2DFactory
类,该类将维护缓存,并用于获取那些
Point2D
实例。
Integer
s只缓存较小的值(如果我没记错的话,为0-127)。和
Double
s(Point2D
所需的)根本不会被缓存。因此,除非坐标始终是0-127范围内的整数,否则您仍然会为每个哈希映射查找创建两个(短期)对象。使用
Point2D
对象作为键看起来更清晰(或者简单地使用
哈希集
)似乎更清楚。@IntegerCache只是缓存少量实例的一个示例。OP需要50个不同的点实例,因此本例中的缓存比IntegerCache小。请参阅Guava的和。看起来很有希望,谢谢@BenManes