Hashtable是否适合存储资产?

时间:2011-01-28 20:01:56

标签: java android actionscript-3

我来自Actionscript3背景,这是我第一次在我的生活中编写任何Java。 Hashtables似乎与Flash中的Dictionaries类似,但我想确保我正确使用它们。我相信Hashtable的类型是接受字符串作为键和字体作为对象。它是否正确?是否有一个不同的Collection子类更适合这样的东西?无论如何,请撕掉我的n00b Java。我需要学习这个。

package com.typeoneerror.apps.app_name.utils;

import android.content.Context;
import android.graphics.Typeface;

import java.util.Hashtable;

public class FontRegistry
{
    private static FontRegistry _instance;

    private Context                         _context;
    private Hashtable<String, Typeface>     _fonts;

    private FontRegistry()
    {
        _fonts = new Hashtable<String, Typeface>();
    }

    public static FontRegistry getInstance()
    {
        if (_instance == null)
        {
            _instance = new FontRegistry();
        }
        return _instance;
    }

    public void init(Context context)
    {
        _context = context;

    }

    public Typeface getTypeface(int resourceId)
    {
        String fontName = _context.getResources().getString(resourceId);
        if (!_fonts.containsKey(fontName))
        {
            String fontPath = "fonts/" + fontName;
            Typeface typeface = Typeface.createFromAsset(_context.getAssets(), fontPath);
            _fonts.put(fontName, typeface);
        }
        return (Typeface)_fonts.get(fontName);
    }
}

2 个答案:

答案 0 :(得分:7)

给你两个建议。

首先,变量类型应该引用Map的接口。这为您的未来提供了更大的灵活性,并且可以与大多数其他Java开发人员更好地融合。

其次,实现应该是HashMap,而不是HashTable。 HashTable会同步所有内容,而HashMap则不会。

如果您确实需要多线程访问,我建议使用ConcurrentHashMap而不是HashTable。 ConcurrentHashMap表现更好,因为它在访问期间不会锁定整个地图。

所以,

private Map<String, Typeface>     _fonts;

_fonts = new HashMap<String, Typeface>();

最后,许多Java开发人员更愿意不使用下划线启动成员变量。虽然这是一个有争议的偏好。

编辑:最后的挑剔。您似乎使用单例模式进行注册表。这可能会在以后咬你,所以考虑避免单身http://accu.org/index.php/journals/337。但是,忽略这一点,你可能最好在声明中实例化单例静态实例。它可以避免在第一次获取时发生争用。

所以:

private static FontRegistry _instance = new FontRegistry;

答案 1 :(得分:1)

要扩展我的评论,getInstance()的实现不是线程安全的。如果你真的必须使用Singleton模式,你可以使用“Bill Pugh”版本(我公开复制了wikipedia article):

public class Singleton {

    // Private constructor prevents instantiation from other classes
    private Singleton() {
    }

    /**
     * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
     * or the first access to SingletonHolder.INSTANCE, not before.
     */
    private static class SingletonHolder { 
        public static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

此外,在为Android开发时,您需要小心,不要“泄漏”Context。这是一个good article,为什么这样做很糟糕,以及如何避免它。底线是staticContext(或自身引用Context的对象)的引用可能意味着您的Activity实例无法进行垃圾回收。