我有以下代码:
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模式的目的是什么?
答案 0 :(得分:2)
Flyweight Pattern是一种重用模式,它通过重用相同的对象来减少程序的内存占用。这与value objects相同,postman website代表诸如单词之类的简单值,因为具有相同字符的单词是相同的。例如,假设我们有以下句子(暂时忽略大写):
the doorman held the door for the guest
这句话有39个字符,这意味着如果我们从这句话创建一个String
,我们将需要存储39个字符(忽略Java length
使用的String
字段暂时实施)。如果我们看一下句子,则the
有3个实例,它们彼此相同。还有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
方法。