11

InternPool<T>我将如何用 Java编写泛型?需要Internable接口吗?

String在 Java 中具有实习能力;我想实习BigDecimalAccount.

4

6 回答 6

6

Interner举个例子,看看Guava。它不需要接口Internable,它只依赖于equalsand hashCode

于 2010-07-24T09:58:03.940 回答
6

像这样的东西:

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;
    }
}

这取决于实现equalshashCode提供“价值平等”的池元素类并遵守这些方法的 API 合同。但BigDecimal肯定会。


更新- 关于为什么我们需要 aWeakHashMap<T, WeakReference<T>>而不是 a的解释WeakHashMap<T, T>,请参阅javadocs。简短的版本是后者中的关键弱链接不会被 GC 破坏,因为相应的条目引用使这些值具有强可达性。

于 2010-07-24T04:58:17.697 回答
3

我会将解决方案分为两个类以拥有更清晰的代码,并以此摆脱循环:

public class WeakPool<T> {
    private final WeakHashMap<T, WeakReference<T>> pool = new WeakHashMap<T, WeakReference<T>>();
    public T get(T object) {
        final T res;
        WeakReference<T> ref = pool.get(object);
        if (ref != null) {
            res = ref.get();
        } else {
            res = null;
        }
        return res;
    }
    public void put(T object) {
        pool.put(object, new WeakReference<T>(object));
    }
}

而使用弱池的实习班非常简单:

public class InternPool<T> {

    private final WeakPool<T> pool = new WeakPool<T>();

    public synchronized T intern(T object) {
        T res = pool.get(object);
        if (res == null) {
            pool.put(object);
            res = object;
        }
        return res;
    }
}
于 2014-02-26T14:14:03.113 回答
2

这听起来更像是您正在寻找轻量级模式

Flyweight是一种软件设计模式。享元是一种通过与其他类似对象共享尽可能多的数据来最小化内存使用的对象

单击链接,它包含一个 Java 示例。

于 2010-07-24T04:30:34.037 回答
1

只是一个快速警告:

上面没有明确提到,但是很明显,被实习的对象 必须不可变的类型。

第二个注意事项:您不需要使用对该对象的另一个弱引用作为映射中的值,如果您仅依赖映射的数据键集,则对静态的引用就足够了。例如,声明:

WeakHashMap<T,Boolean>

并插入对:

pool.put (object, Boolean.TRUE);

这是对 WeakReference 实例的少量保存(如果您不能重用用于密钥的实例)。

...或者创建一个 WeakSet 类,就像@PeterVerhas 对他的 WeakPool 所做的那样。

于 2014-10-27T11:26:35.150 回答
-1

不应该

“弱引用 ref = pool.get(object);”

而是

弱引用 ref = pool.intern(object);

??

于 2015-09-10T15:47:41.497 回答