API Demo SearchableDictionary代码分析二

来源:互联网 发布:网络摄像机手机客户端 编辑:程序博客网 时间:2024/05/21 13:22

字典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里面返回这个键对应的所有值就可以了。



原创粉丝点击