Как я записал бы дженерик InternPool<T>
в Java? Этому нужен a Internable
интерфейс?
String
в Java имеет возможности интернирования; я хочу интернировать классы как BigDecimal
и Account
.
Это больше похоже на то, что вы ищете образец наилегчайшего веса .
Легковес - это шаблон проектирования программного обеспечения. Легковес - это объект, который сводит к минимуму использование памяти, разделяя как можно больше данных с другими подобными объектами
Щелкните ссылку, она содержит пример Java.
Для примера взгляните на Interner
из Гуава . Он не требует Интернируемый
интерфейс, он просто полагается на равняется
и хэш-код
.
Примерно так:
public class InternPool<T> {
private WeakHashMap<T, WeakReference<T>> pool =
new WeakHashMap<T, WeakReference<T>>();
public synchronized T intern(T object) {
T res = null;
// (The loop is needed to deal with race
// conditions where the GC runs while we are
// accessing the 'pool' map or the 'ref' object.)
do {
WeakReference<T> ref = pool.get(object);
if (ref == null) {
ref = new WeakReference<T>(object);
pool.put(object, ref);
res = object;
} else {
res = ref.get();
}
} while (res == null);
return res;
}
}
Это зависит от класса элемента пула, реализующего равно
и hashCode
, чтобы обеспечить «равенство по значению» и подчиняться контрактам API для этих методы. Но BigDecimal
определенно имеет значение.
ОБНОВЛЕНИЕ - для объяснения того, почему нам нужна WeakHashMap
, а не WeakHashMap
, см. javadocs . Краткая версия заключается в том, что ключевые слабые звенья в последнем не будут нарушены сборщиком мусора, потому что соответствующие ссылки на записи делают значения полностью достижимыми.