簡體   English   中英

java中的享元設計模式,目的是什么?

[英]Flyweight design pattern in java, what is the purpose?

我有以下代碼:

public class Sentence {

    private String [] words;
    private Map<Integer, WordToken> tokens = new HashMap<>();

    public Sentence(String plainText) {
        words = plainText.split(" ");
    }

    public WordToken getWord(int index) {
        WordToken wt = new WordToken();
        tokens.put(index, wt);
        return tokens.get(index);
    }

    @Override
    public String toString() {
        List<String> ws = new ArrayList<>();
        for (int i = 0; i < words.length; ++i) {
            String w = words[i];
            if (tokens.containsKey(i) && tokens.get(i).capitalize) {
                w = w.toUpperCase();
            }
            ws.add(w);
        }
        return String.join(" ", ws);
    }
}

並測試:

@Test
public void test() {
    Sentence s = new Sentence("alpha beta gamma");
    s.getWord(1).capitalize = true;
    assertEquals("alpha BETA gamma", s.toString());
}

我的問題是:以這種方式使用享元模式的目的是什么?

Flyweight 模式是一種重用模式,它通過重用相同的對象來減少程序的內存占用。 這對於表示簡單值(例如單詞)的值對象很常見,因為具有相同字符的單詞是相同的。 例如,假設我們有以下句子(暫時忽略大小寫):

the doorman held the door for the guest

這句話有 39 個字符,這意味着如果我們從這句話創建一個String ,我們將需要存儲 39 個字符(暫時忽略 Java String實現使用的length字段)。 如果我們看一下這句話,也有3個實例the ,它們彼此相同。 還有7個空格,它們彼此相同。 如果我們對字符串進行標記,我們將獲得以下單詞:

["the", "doorman", "held", "the", "door", "for", "the", "guest"]

如果我們只取這個列表中的唯一值,我們得到:

["the", "doorman", "held", "door", "for", "guest"]

使用這些獨特的詞,我們可以通過將句子中的詞的索引映射到獨特的詞來創建句子:

[0, 1, 2, 0, 3, 4, 0, 5]

為了重建句子,我們將上面的索引簡單地映射到唯一詞的列表,在每個詞之間添加一個空格。

在您提供的示例中,該算法似乎不正確(它不節省任何空間,因為它同時存儲了單詞和標記)。 更正確的解決方案(眾多解決方案之一)類似於):

public class Sentence {

    private final List<Integer> wordMap = new ArrayList<>();
    private final List<String> words = new ArrayList<>();

    public Sentence(String sentence) {
        for (String word: sentence.split(" ")) {
            addIfNotExists(word);
            wordMap.add(words.indexOf(word));
        }
    }

    private void addIfNotExists(String word) {

        if (!words.contains(word)) {
            words.add(word);
        }
    }

    public List<Integer> getWordMap() {
        return wordMap;
    }

    public List<String> getWords() {
        return words;
    }

    public static void main(String[] args) {
        Sentence s = new Sentence("the doorman held the door for the guest");
        System.out.println(s.getWordMap());
        System.out.println(s.getWords());
    }
}

運行此結果會產生以下輸出:

[0, 1, 2, 0, 3, 4, 0, 5]
[the, doorman, held, door, for, guest]

我把它留給你來實現toString方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM