现在的位置: 首页 > 综合 > 正文

API Demo SearchableDictionary代码分析二

2013年01月01日 ⁄ 综合 ⁄ 共 3426字 ⁄ 字号 评论关闭

字典Directory类的分析,在这个程序中这个Directory相当于是数据源,也就是相当于数据库,而DictionaryProvider相当于操作这个数据库的类

public class Dictionary {

    public static class Word {
        public final String word;
        public final String definition;

        public Word(String word, String definition) {
            this.word = word;
            this.definition = definition;
        }
    }

    private static final Dictionary sInstance = new Dictionary();

    public static Dictionary getInstance() {
        return sInstance;
    }

    private final Map<String, List<Word>> mDict = new ConcurrentHashMap<String, List<Word>>();

    private Dictionary() {
    }

    private boolean mLoaded = false;

    /**
     * Loads the words and definitions if they haven't been loaded already.
     *
     * @param resources Used to load the file containing the words and definitions.
     */
    public synchronized void ensureLoaded(final Resources resources) {
        if (mLoaded) return;

        new Thread(new Runnable() {
            public void run() {
                try {
                    loadWords(resources);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }

    private synchronized void loadWords(Resources resources) throws IOException {
        if (mLoaded) return;

        Log.d("dict", "loading words");
        InputStream inputStream = resources.openRawResource(R.raw.definitions);
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

        try {
            String line;
            while((line = reader.readLine()) != null) {
                String[] strings = TextUtils.split(line, "-");
                if (strings.length < 2) continue;
                addWord(strings[0].trim(), strings[1].trim());
            }
        } finally {
            reader.close();
        }
        mLoaded = true;
    }


    public List<Word> getMatches(String query) {
        List<Word> list = mDict.get(query);
        return list == null ? Collections.EMPTY_LIST : list;
    }

    private void addWord(String word, String definition) {
        final Word theWord = new Word(word, definition);

        final int len = word.length();
        for (int i = 0; i < len; i++) {
            final String prefix = word.substring(0, len - i);
            addMatch(prefix, theWord);
        }
    }

    private void addMatch(String query, Word word) {
        List<Word> matches = mDict.get(query);
        if (matches == null) {
            matches = new ArrayList<Word>();
            mDict.put(query, matches);
        }
        matches.add(word);
    }
}

当我们查询以字母g开头的单词时会将所有以g开头的单词显示出来:

这里是启动一个线程来记载这些单词的:

public synchronized void ensureLoaded(final Resources resources) {
        if (mLoaded) return;

        new Thread(new Runnable() {
            public void run() {
                try {
                    loadWords(resources);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }

    private synchronized void loadWords(Resources resources) throws IOException {
        if (mLoaded) return;

        Log.d("dict", "loading words");
        InputStream inputStream = resources.openRawResource(R.raw.definitions);
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

        try {
            String line;
            while((line = reader.readLine()) != null) {
                String[] strings = TextUtils.split(line, "-");
                if (strings.length < 2) continue;
                addWord(strings[0].trim(), strings[1].trim());
            }
        } finally {
            reader.close();
        }
        mLoaded = true;
    }

这里用一个变量mLoad来控制是否加载单词,如果加载了即使下次调用了这个线程也会推出这个线程。这里按照<Java多线程设计模式>上应该是属于Balking(不需要的话,就算了吧),在警戒条件不成立时,线程会直接退出。

private void addWord(String word, String definition) {
        final Word theWord = new Word(word, definition);

        final int len = word.length();
        for (int i = 0; i < len; i++) {
            final String prefix = word.substring(0, len - i);
            addMatch(prefix, theWord);
        }
    }

将这个单词的每个字母加到列表里面

private void addMatch(String query, Word word) {
        List<Word> matches = mDict.get(query);
        if (matches == null) {
            matches = new ArrayList<Word>();
            mDict.put(query, matches);
        }
        matches.add(word);
    }

如果某个单词的某个字母作为键在这个private final Map<String, List<Word>> mDict = new ConcurrentHashMap<String, List<Word>>();里面是否有值,如果有就在这个键对应的值里面加上,如果没有就创建一个然后加上。

这里需要注意一点:

 List<Word> matches = mDict.get(query);

matches.add(word);

也就是说返回的是List的地址,我在这上面添加数据,在mDict里面也相应的改变了
这样的话当要搜索某个字母开头的单词的话:

public List<Word> getMatches(String query) {
        List<Word> list = mDict.get(query);
        return list == null ? Collections.EMPTY_LIST : list;
    }

只要从mDict里面返回这个键对应的所有值就可以了。

抱歉!评论已关闭.