Java 如何优化此代码?
我当前的项目让我们在Java中使用TreeSet和TreeMap,并从文本文件中读取10514个歌曲元素的输入数组。每首歌都包含一个艺术家、标题和歌词字段。这个项目的目的是使用集合和地图对歌词进行快速搜索 首先,我迭代输入歌曲数组,访问歌词字段并创建一个Scanner对象以使用以下代码迭代歌词:Java 如何优化此代码?,java,optimization,build-time,Java,Optimization,Build Time,我当前的项目让我们在Java中使用TreeSet和TreeMap,并从文本文件中读取10514个歌曲元素的输入数组。每首歌都包含一个艺术家、标题和歌词字段。这个项目的目的是使用集合和地图对歌词进行快速搜索 首先,我迭代输入歌曲数组,访问歌词字段并创建一个Scanner对象以使用以下代码迭代歌词:commonWords是一个不应该是键的单词树集,lyricWords是单词到歌曲的整体映射 public void buildSongMap() { for (Song song:songs)
commonWords
是一个不应该是键的单词树集,lyricWords
是单词到歌曲的整体映射
public void buildSongMap() {
for (Song song:songs) {
//method variables
String currentLyrics= song.getLyrics().toLowerCase();
TreeSet<Song> addToSet=null;
Scanner readIn= new Scanner(currentLyrics);
String word= readIn.next();
while (readIn.hasNext()) {
if (!commonWords.contains(word) && !word.equals("") && word.length()>1) {
if (lyricWords.containsKey(word)) {
addToSet= lyricWords.get(word);
addToSet.add(song);
word=readIn.next();
} else
buildSongSet(word);
} else
word= readIn.next();
}
}
public void buildSongMap(){
用于(歌曲:歌曲){
//方法变量
字符串currentLyps=song.getLyps().toLowerCase();
TreeSet addToSet=null;
扫描仪读入=新扫描仪(当前歌词);
String word=readIn.next();
while(readIn.hasNext()){
如果(!commonWords.contains(word)&&!word.equals(“”&&word.length()>1){
if(抒情词.containsKey(词)){
addToSet=lyricWords.get(word);
addToSet.add(歌曲);
word=readIn.next();
}否则
构建歌曲集(word);
}否则
word=readIn.next();
}
}
为了构建歌曲集,我使用以下代码:
public void buildSongSet(String word) {
TreeSet<Song> songSet= new TreeSet<Song>();
for (Song song:songs) {
//adds song to set
if (song.getLyrics().contains(word)) {
songSet.add(song);
}
}
lyricWords.put(word, songSet);
System.out.println("Word added "+word);
}
public void buildSongSet(字符串词){
TreeSet songSet=新TreeSet();
用于(歌曲:歌曲){
//将歌曲添加到场景中
if(song.getlymps().contains(word)){
歌曲集。添加(歌曲);
}
}
歌词。放(词,歌曲集);
System.out.println(“添加单词”+单词);
}
现在,由于buildSongSet是从循环内部调用的,因此创建映射只需N^2次。当输入数组为4首歌曲时,搜索运行速度非常快,但当使用10514个元素的完整数组时,在一台2.4GHz、内存为6 GiB的机器上构建映射可能需要15分钟以上的时间。我可以做些什么来提高代码的效率?不幸的是,减少输入数据无效。看起来您的buildSongSet正在做冗余工作。您的块:
if (lyricWords.containsKey(word)) {
addToSet= lyricWords.get(word);
addToSet.add(song);
word=readIn.next();
}
将歌曲添加到现有集。因此,当您发现一个不知道的单词时,只需向其中添加一首歌曲。将buildSongSet更改为:
public void buildSongSet(String word, Song firstSongWithWord) {
TreeSet<Song> songSet= new TreeSet<Song>();
songSet.add(firstSongWithWord);
lyricWords.put(word, songSet);
System.out.println("Word added "+word);
}
public void buildSongSet(String word,Song firstsong with word){
TreeSet songSet=新TreeSet();
歌曲集。添加(第一首歌曲WithWord);
歌词。放(词,歌曲集);
System.out.println(“添加单词”+单词);
}
剩下的要迭代的歌曲将从第一段代码中添加到歌曲集中,如果它们包含那个词的话。我认为这样应该可以
编辑刚刚看到这是家庭作业…所以删除了HashSet建议
好吧,假设你把这些歌曲和歌词按顺序排列:
- 宋一福
- 歌曲2-富吧
- 歌曲3-富吧
编辑另请参见-那里有额外的加速,但大的加速正在摆脱内部循环-很高兴现在已降到15秒。看起来您的buildSongSet正在做冗余工作。您的块:
if (lyricWords.containsKey(word)) {
addToSet= lyricWords.get(word);
addToSet.add(song);
word=readIn.next();
}
将歌曲添加到现有集。因此,当您发现一个不知道的单词时,只需向其中添加一首歌曲。将buildSongSet更改为:
public void buildSongSet(String word, Song firstSongWithWord) {
TreeSet<Song> songSet= new TreeSet<Song>();
songSet.add(firstSongWithWord);
lyricWords.put(word, songSet);
System.out.println("Word added "+word);
}
public void buildSongSet(String word,Song firstsong with word){
TreeSet songSet=新TreeSet();
歌曲集。添加(第一首歌曲WithWord);
歌词。放(词,歌曲集);
System.out.println(“添加单词”+单词);
}
剩下的要迭代的歌曲将从第一段代码中添加到歌曲集中,如果它们包含那个词的话。我认为这样应该可以
编辑刚刚看到这是家庭作业…所以删除了HashSet建议
好吧,假设你把这些歌曲和歌词按顺序排列:
- 宋一福
- 歌曲2-富吧
- 歌曲3-富吧
编辑还可以看到-那里有额外的加速,但是大的加速已经摆脱了内部循环-很高兴现在降到了15秒。请尝试将TreeSet更改为HashSet。我看不到您从何处获得TreeSet的好处。请尝试将TreeSet更改为HashSet。我看不到您从何处获得TreeSet的好处 imho不需要整个
buildSongSet()
方法,因为您的主循环已将歌曲按单词添加到集合中。您唯一缺少的是为新词添加一个集合,例如:
if (lyricWords.containsKey(word)) {
addToSet= lyricWords.get(word);
} else {
addToSet = new TreeSet();
lyricWords.put(word, addToSet);
}
addToSet.add(song);
你没有解决的一个问题就是那首歌