我試圖從TreeMap中的單個鍵檢索多個值。這個想法是,每個關鍵將鏈接到多個值,應該可以搜索。現在我遇到的麻煩是,當我只能從密鑰中獲得一個值時。Java TreeMap:從單個鍵檢索多個值
關鍵是一個字符串,該值是一個自定義對象,稱爲宋。歌曲包含多個元素。目標是從每首歌中逐字提取歌詞,並將每個單詞用作關鍵詞。該鍵然後鏈接到包含該鍵的每個樂曲(值)。
我已經搜索了StackOverFlow和一般的網絡技巧,我已經看到了一些,但沒有直接解決我的絆腳石。我看到的一個想法是將值更改爲某種數組或列表。我可能會在明天刷新大腦時嘗試。
無論如何,預先感謝您的任何提示和建議。是的,這是作業。不,我沒有標記是因爲我被告知,作業標籤不再被普遍使用。
代碼:
public class SearchByLyricsWords {
private static Song[] songs;
private static TreeMap<String, Song> lyricsTreeMap = new TreeMap<String, Song>();
private static TreeSet<String> wordsToIgnoreTree = new TreeSet<String>();
private static File wordsToIgnoreInput = new File("ignore.txt");
private static String wordsToIgnoreString;
private static String[] wordsToIgnoreArray;
private Song[] searchResults; // holds the results of the search
private ArrayList<Song> searchList = new ArrayList<Song>();
public SearchByLyricsWords(SongCollection sc) throws FileNotFoundException {
// Create a string out of the ignore.txt file
Scanner scanInputFile = new Scanner(wordsToIgnoreInput);
String ignoreToken = scanInputFile.next();
ignoreToken.toLowerCase();
wordsToIgnoreString = ignoreToken + " ";
while (scanInputFile.hasNext()) {
ignoreToken = scanInputFile.next();
wordsToIgnoreString = wordsToIgnoreString + ignoreToken + " ";
}
// Split the string created from ignore.txt
wordsToIgnoreArray = wordsToIgnoreString.split("[^a-zA-Z]+");
// Fill a TreeSet from the wordsToIgnoreArray
for (int i = 0; i < wordsToIgnoreArray.length; i++) {
ignoreToken = wordsToIgnoreArray[i];
wordsToIgnoreTree.add(ignoreToken);
}
// Fill TreeMap with lyrics words as the key, Song objects as the value
songs = sc.getAllSongs();
for (int j = 0; j < songs.length; j++) {
Song currentSong = songs[j];
String lyrics = currentSong.getLyrics();
TreeSet<String> lyricsFound = new TreeSet<String>();
String lyricsToken;
String[] songLyricsArray;
songLyricsArray = lyrics.split("[^a-zA-Z]+");
for (int k = 0; k < songLyricsArray.length; k++) {
lyricsToken = songLyricsArray[k];
if (lyricsToken.length() <= 1) {
continue;
}
lyricsFound.add(lyricsToken);
}
lyricsFound.removeAll(wordsToIgnoreTree);
Iterator<String> iterator = lyricsFound.iterator();
while(iterator.hasNext()) {
String currentWord = (String)iterator.next();
lyricsTreeMap.put(currentWord, currentSong);
}
//System.out.println(lyricsTreeMap); // testing only
}
}
public Song[] search(String lyricsWords) {
lyricsWords = lyricsWords.toLowerCase();
TreeSet<String> searchTree = new TreeSet<String>();
String searchToken;
String[] lyricsWordsSearch = lyricsWords.split("[^a-zA-Z]+");
for (int l = 0; l < lyricsWordsSearch.length; l++) {
searchToken = lyricsWordsSearch[l];
if (searchToken.length() <= 1) {
continue;
}
searchTree.add(searchToken);
}
searchTree.removeAll(wordsToIgnoreTree);
Iterator<String> searchIterator = searchTree.iterator();
while(searchIterator.hasNext()) {
String currentSearchWord = (String)searchIterator.next();
Collection<Song> lyricsTreeCollection = lyricsTreeMap.values();
while (lyricsTreeMap.containsKey(currentSearchWord) == true) {
Iterator collectionIterator = lyricsTreeCollection.iterator();
while(collectionIterator.hasNext() && collectionIterator.next() == currentSearchWord) {
Song searchSong = lyricsTreeMap.get(currentSearchWord);
searchList.add(searchSong);
}
}
}
searchResults = searchList.toArray(new Song[searchList.size()]);
Arrays.sort(searchResults);
return searchResults;
}
Darn。好吧,我的誤解。我知道鑰匙必須是唯一的,但我不明白他們只會映射到一個值。謝謝。 –
我認爲內部結構應該是'Set'而不是'List'以存儲將自動省略密鑰的冗餘值的值。 –
這在分配的上下文中是有意義的。我的印象是,在TreeMap中,這個值是作爲一個集合運行的。正如你所知道的,我仍然(努力)學習這些東西。謝謝回覆。 –