【发布时间】:2010-11-08 20:56:10
【问题描述】:
我当前的项目需要对歌曲的歌词进行搜索,这是 Song 对象中的 String 字段。为了帮助提高搜索效率,我在创建歌曲对象时使用String.split("[^a-zA-Z]"); 将歌词转储到一个集合中以创建一个字符串数组,然后添加到一个集合中。
有没有一种特定的方法可以将单词添加到集合中而无需创建数组的中间步骤?
【问题讨论】:
我当前的项目需要对歌曲的歌词进行搜索,这是 Song 对象中的 String 字段。为了帮助提高搜索效率,我在创建歌曲对象时使用String.split("[^a-zA-Z]"); 将歌词转储到一个集合中以创建一个字符串数组,然后添加到一个集合中。
有没有一种特定的方法可以将单词添加到集合中而无需创建数组的中间步骤?
【问题讨论】:
你会搜索特定歌曲中的一些单词吗?如果是这样,您可能真的不需要为此设置,您可以从获得歌词的位置开始搜索。您可以为此使用纯正则表达式,这可能比拆分字符串、将其放入集合并查询集合要快一些:
public class RegexpExample {
public static void main(String[] args) {
String song = "Is this a real life? Is this just fantasy?";
String toFind = "is";
Pattern p = Pattern.compile(toFind, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(song);
while (m.find()) {
String found = m.group();
int startIndex = m.start();
int endIndex = m.end();
System.out.println(found + " at start " + startIndex + ", end " + endIndex);
//do something with this info...
}
}
它会输出这个:
Is at start 0, end 2
is at start 5, end 7
Is at start 21, end 23
is at start 26, end 28
如果你在不同的歌曲中搜索,你可以使用StringBuilder连接他们的歌词,然后调用StringBuilder#toString并使用toString方法的结果进行整个操作
【讨论】:
有没有特定的方法可以将单词添加到没有 创建数组的中间步骤?
当然,您可以编写一个返回 Iterator 对象的方法,该对象一次输入一个单词。
但是像这样的东西真的不值得优化。您的数组很容易小到足以放入内存中,它的创建不会那么昂贵,然后垃圾收集器会清理它。
【讨论】:
StringTokenizer st = new StringTokenizer("the days go on and on without you here");
HashSet<String> words = new HashSet<String>();
while (st.hasMoreTokens()) {
words.add(st.nextToken());
}
【讨论】:
StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead. 有趣的解决方案,不过
我不知道效率,但或者,你可以这样做:
import java.io.StringReader;
// ...
public static Set<String> getLyricSet(String lyrics) throws IOException {
StringReader sr = new StringReader(lyrics);
StringBuilder sb = new StringBuilder();
Set<String> set = new HashSet<String>();
int current;
// Read characters one by one, returns -1 when we're done
while ((current = sr.read()) != -1) {
if (Character.isWhitespace(current)) {
// End of word, add current word to set.
set.add(sb.toString());
sb = new StringBuilder();
} else {
sb.append((char) current);
}
}
// End of lyrics, add current word to set.
set.add(sb.toString());
sr.close();
return set;
}
【讨论】: