Java TreeMap : Retrieving multiple values from a single key

标签 java key treemap treeset

我正在尝试从 TreeMap 中的单个键检索多个值。这个想法是每个键都将链接到多个值并且应该是可搜索的。现在我遇到的麻烦是当我只能从 key 中取回一个值时。

键是一个字符串,值是一个自定义对象,称为 Song。歌曲包含多种元素。目标是从每首歌中逐字提取歌词,并将每个单词用作关键字。该键然后链接到包含该键的每首歌曲(值)。

我在 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;
}

最佳答案

TreeMap每个键只保留一个值,as with all Map implementations :

A map cannot contain duplicate keys; each key can map to at most one value.

您的备选方案包括

  • 使用TreeMap<String, List<Song>>相反,手动处理 List值(value)观并保持更新
  • 使用e.g. a TreeMultimap 来自 Guava,它(或多或少)像 TreeMap<K, TreeSet<V>> 一样运行,除了好多了。 (披露:我为 Guava 做出了贡献。)

关于Java TreeMap : Retrieving multiple values from a single key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13355721/

相关文章:

Java:来自 TreeMap 条目的迭代器?

java - 服务器端从另一个客户端获取 GET 请求时推送到客户端

java - 使用 JMeter 加载测试结果 - 最小/最大时间给出 NaN

java - 如何重写 SocketChannelImpl 类以便在两个不同的 SocketChannelImpl 对象中使用相同的 FileDescriptor?

java - 使用 Maven 创建 Wicket 项目

python - 哪个 Python 模块可以在 while 循环中监控 3 个按键组合?

dictionary - 按确定对象的总和进行流分组

java - 使用监视文件夹重新启动线程

arrays - 如何从渲染列表中访问对象键?

java - 如何整理一个TreeMap<String, Integer>?