2011-01-28 26 views
5

Tôi đến từ một nền Actionscript3 và đây là lần đầu tiên tôi viết bất kỳ Java nào trong cuộc đời của tôi. Hashtables có vẻ tương tự như Từ điển trong Flash, nhưng tôi muốn đảm bảo rằng tôi đang sử dụng chúng một cách chính xác. Tôi tin rằng Hashtable được gõ để chấp nhận các chuỗi như các phím và kiểu chữ làm đối tượng. Điều này có đúng không? Có một lớp con Bộ sưu tập khác sẽ thích hợp hơn cho một thứ như thế này không? Bởi tất cả các phương tiện, xin vui lòng xé n00b của tôi Java lên. Tôi cần phải học điều này.Có phải Hashtable thích hợp để lưu trữ nội dung không?

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

Ngoại trừ những gì rfeak đã nói, nó ổn. Một số mẹo khác: Khi bạn bỏ dấu gạch dưới (làm ơn), thì bạn cần 'this.context = context'. Bạn có thể khởi tạo các phông chữ như 'Bản đồ cuối cùng riêng tư fonts = new HashMap ()'. Nếu có đồng thời, sau đó bạn có thể nhận được vấn đề với singleton lười biếng của bạn. Bật cảnh báo, diễn viên cuối cùng của bạn chắc chắn là không cần thiết. – maaartinus

+1

Quyền truy cập vào lớp này có phải là một hoặc nhiều luồng không? Tôi chỉ yêu cầu như hiện tại của bạn 'getInstance()' không phải là luồng an toàn. –

+0

@ dave.c Tôi phải thừa nhận là tôi không biết. Như tôi đã nói, đây là lần đầu tiên tôi viết java, vì vậy mọi lời khuyên về điều đó như một câu trả lời sẽ được đánh giá cao. – typeoneerror

Trả lời

7

Hai đề xuất cho bạn.

Đầu tiên, loại biến nên tham chiếu đến giao diện của Bản đồ. Điều này mang lại cho bạn sự linh hoạt hơn cho tương lai và sẽ tốt hơn với hầu hết các nhà phát triển Java khác.

Thứ hai, triển khai phải là HashMap chứ không phải HashTable. HashTable đồng bộ hóa mọi thứ, trong đó HashMap thì không.

Nếu bạn cần truy cập đa luồng, tôi khuyên bạn nên sử dụng ConcurrentHashMap thay vì HashTable. ConcurrentHashMap hoạt động tốt hơn, vì nó không khóa toàn bộ bản đồ trong khi truy cập.

Vì vậy,

private Map<String, Typeface>  _fonts; 

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

Cuối cùng, nhiều nhà phát triển Java muốn mà bạn không bắt đầu biến thành viên với dấu gạch dưới. Mặc dù đây là một sở thích đáng tranh cãi.

EDIT: Một nitpick cuối cùng. Dường như bạn đang sử dụng mẫu đơn cho đăng ký. Điều này có thể cắn bạn sau này, vì vậy hãy cân nhắc tránh những người độc thân http://accu.org/index.php/journals/337. Nhưng, bỏ qua điều đó, bạn có thể tốt hơn để khởi tạo thể hiện tĩnh đơn tại bản khai. Nó có thể tránh tranh chấp khi tìm nạp nó lần đầu tiên.

Vì vậy:

private static FontRegistry _instance = new FontRegistry; 
+0

câu trả lời tuyệt vời, cảm ơn bạn.Tôi cũng không phải là fan của mẫu đơn singleton. có lẽ sẽ tái cấu trúc. – typeoneerror

+1

Mẫu đơn với một 'Context' là thành viên' tĩnh' cũng nguy hiểm trong Android vì nó có thể ngăn chặn 'Hoạt động' được chuyển thành một' Ngữ cảnh' khỏi bị thu gom rác. –

1

Mở rộng trên ý kiến ​​của tôi, thực hiện lại getInstance() không phải là thread an toàn. Nếu bạn thực sự phải sử dụng mẫu Singleton, bạn có thể sử dụng phiên bản "Bill Pugh" (mà tôi đã ngang nhiên sao chép từ 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; 
    } 
} 

Ngoài ra bạn cần phải cẩn thận khi phát triển dành cho Android không để "rò rỉ "a Context. Dưới đây là một số good article về lý do tại sao làm như vậy là xấu và cách tránh điều đó. Điểm mấu chốt là một tham chiếu static đến một số Context (hoặc một đối tượng tự tham chiếu Context) có thể có nghĩa là trường hợp Activity của bạn không thể được thu thập rác.

+0

cảm ơn bạn đã viết thư này, dave. – typeoneerror

+0

liên kết tuyệt vời. Tôi nên lưu ý rằng tôi đang sử dụng ngữ cảnh Ứng dụng cho trình khởi tạo: FontRegistry.getInstance(). Init (getApplicationContext()); . bài viết quy định rằng "... ngữ cảnh ứng dụng. Ngữ cảnh này sẽ sống miễn là ứng dụng của bạn còn sống và không phụ thuộc vào vòng đời hoạt động" – typeoneerror

+0

Rất vui khi bạn thấy chúng hữu ích. Khi bạn nói, sử dụng 'getApplicationContext()' là một cách để tránh vấn đề. –

Các vấn đề liên quan