编写实例控制类

时间:2015-08-23 13:37:24

标签: java

我想创建一个包含私有构造函数和静态工厂方法of的类。我希望of始终返回具有指定字段的类的现有实例,如果已创建此类实例但尚未由垃圾收集器收集。

我不想简单地保留Set个实例,因为这会阻止实例被垃圾回收。我考虑过保留WeakHashMapSet<WeakReference>,但这会将of缩减到搜索范围,如果尺寸变大则会损害性能。

我想到的解决方案是这样的:

public final class Widget {

    private static final Map<Integer, Set<Reference<Widget>>> map = new HashMap<>();

    private final String string;
    private final int value;

    private Widget(String string, int value) {
        this.string = string;
        this.value = value;
    }

    public static Widget of(String string, int value) {
        if (string == null)
            throw new NullPointerException();
        int hash = 31 * string.hashCode() + value;
        Set<Reference<Widget>> set = map.get(hash);
        if (set == null) {
            set = new HashSet<>();
            map.put(hash, set);
        } else {
            for (Iterator<Reference<Widget>> i = set.iterator(); i.hasNext();) {
                Widget widget = i.next().get();
                if (widget == null)
                    i.remove();
                else if (widget.string.equals(string) && widget.value == value)
                    return widget;
            }
        }
        Widget widget = new Widget(string, value);
        set.add(new WeakReference<>(widget));
        return widget;
    }

    static void tidy() {
        for (Iterator<Set<Reference<Widget>>> i = map.values().iterator(); i.hasNext();) {
            Set<Reference<Widget>> set = i.next();
            for (Iterator<Reference<Widget>> i2 = set.iterator(); i2.hasNext();)
                if (i2.next().get() == null)
                    i2.remove();
            if (set.isEmpty())
                i.remove();
        }
    }
}

此解决方案的问题在于您必须定期调用tidy()方法,而我真的希望所有整理都能自动完成。

这个问题有简单或标准的解决方案吗?

0 个答案:

没有答案