简体   繁体   English

在Java中缓存和重用不可变单例对象的最佳方法是什么?

[英]What is the best way to cache and reuse immutable singleton objects in Java?

I have a class representing a set of values that will be used as a key in maps. 我有一个表示一组值的类,这些值将用作地图中的键。

This class is immutable and I want to make it a singleton for every distinct set of values, using the static factory pattern. 此类是不可变的,我想使用静态工厂模式将其用于每个不同的值集。 The goal is to prevent identical objects from being created many (100+) times and to optimize the equals method. 目的是防止相同的对象创建多次(100+)次,并优化equals方法。

I am looking for the best way to cache and reuse previous instances of this class. 我正在寻找缓存和重用该类以前的实例的最佳方法。 The first thing that pops to mind is a simple hashmap, but are there alternatives? 我想到的第一件事是一个简单的哈希图,但是有替代方法吗?

There are two situations: 有两种情况:

  • If the number of distinct objects is small and fixed, you should use an enum 如果不同对象的数量很小且固定,则应使用enum
    • They're not instantiatiable beyond the declared constants, and EnumMap is optimized for it 它们无法在声明的常量之外实例化,并且EnumMap为此进行了优化。
  • Otherwise, you can cache immutable instances as you planned: 否则,您可以按计划缓存不可变的实例:
    • If the values are indexable by numbers in a contiguous range, then an array can be used 如果值可以用连续范围内的数字索引,则可以使用数组
      • This is how eg Integer cache instances in a given range for valueOf 例如,这是给定范围内valueOf Integer缓存实例
    • Otherwise you can use some sort of Map 否则,您可以使用某种Map

Depending on the usage pattern, you may choose to only cache, say, the last N instances, instead of all instances created so far. 根据使用模式,您可以选择仅缓存(例如,最后N个)实例,而不是缓存迄今为止创建的所有实例。 This is the approach used in eg re.compile in Python's regular expression module. 这是在Python的正则表达式模块中进行重新re.compile的方法。 If N is small enough (eg 5), then a simple array with a linear search may also work just fine. 如果N足够小(例如5),则具有线性搜索的简单数组也可以正常工作。

For Map based solution, perhaps a useful implementation is java.util.LinkedHashMap , which allows you to enforce LRU-like policies if you @Override the removeEldestEntry . 对于基于Map的解决方案,也许有用的实现是java.util.LinkedHashMap ,如果您@Override removeEldestEntry ,它可以强制执行类似LRU的策略。

There is also LRUMap from Apache Commons Collections that implement this policy more directly. 还有来自Apache Commons Collections的 LRUMap ,它们可以更直接地实施此策略。

See also 也可以看看

Related questions 相关问题

What you're trying to make sounds like an example of the Flyweight Pattern , so looking for references to that might help clarify your thinking. 您尝试做的听起来像是Flyweight Pattern的示例,因此寻找对此的引用可能有助于阐明您的想法。

Storing them in a map of some sort is indeed a common implementation. 将它们存储在某种类型的地图中确实是一种常见的实现。

What do your objects look like? 您的对象是什么样的? If your objects are fairly simple I think you should consider not caching them - object creation is usually quite fast. 如果您的对象非常简单,我认为您应该考虑不缓存它们-对象创建通常非常快。 I think you should evaluate whether the possibly small performance boost is worth the added complexity and effort of a cache. 我认为您应该评估可能较小的性能提升是否值得增加缓存的复杂性和工作量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM