如何在Hashmap <hashmap <arraylist>&gt; </hashmap <arraylist>中存储位置索引和文档ID

时间:2012-01-13 12:40:28

标签: java text arraylist hashmap

我在目录中有文本文件。我需要做的是;
---对于所有文件中的每个单词
---找到文件中每个单词的位置索引
---找到单词已通过的每个文件

为了做到这一点;

HashMap<String, HashMap<Integer, ArrayList<Integer>>>

我想使用上面的结构。

String word;
        String pattern = "[[^\\w\\süÜıİöÖşŞğĞçÇ]\\d]+";
        while ((word = infile.readLine()) != null) {
            String[] wordList = word.replaceAll(pattern, " ").split("\\s+");

            for (int j = 0; j < wordList.length; j++) {
                if(!wordList[j].isEmpty()){
                        if(!refinedDict.containsKey(wordList[j])){
                            refinedDict.put(wordList[j], 1);
                        }
                        else{
                            refinedDict.put(wordList[j], refinedDict.get(wordList[j])+1);
                        }
                    }//end of for
                 }//end if
                else{
                 //do something   
                }
            }//end for
        }//end while

 Set<String> keys=refinedDict.keySet();
 List<String> list=sortList(keys);
 Iterator<String> it=list.iterator();
 while(it.hasNext()){
       String key=it.next();
       outfile.write(key + "\t" + refinedDict.get(key) + "\n");



如何在HashMap中使用HashMap中的ArrayList

修改
应用toto2的解决方案实施后。但是,为了将其写为文件---&gt;
word [fileId {positions},fileId {positions} ...]
可以做些什么?
实现serializable对于这样的设计没有用。

4 个答案:

答案 0 :(得分:1)

为了清楚起见,我定义了两个新类FileIdPositionInFile而不是Integer

Map<String, Map<FileId, List<PositionInFile>>> wordsWithLocations;

for (int j = 0; j < wordList.length; j++) {
   if (!wordList[j].isEmpty()){
      if (!wordsWithLocations.containsKey(wordList[j])) {
         Map<FileId, List<PositionInFile>> map = new HashMap<>();
         List<PositionInFile> list = new ArrayList<>();
         list.add(wordPosition[j]);
         map.put(fileId, list);
         wordsWithLocations.put(wordList[j], map);
       } else {
          Map<FileId, List<PositionInFile>> map = 
                          wordsWithLocation.get(wordList[j]);
          if (map.contains(fileId)) {
             map.get(fileId).add(wordPosition[j]);
          } else {
             List<PositionInFile> list = new ArrayList<>();
             list.add(wordPosition[j]);
             map.put(fileId, list);
          }
       }
    }
}

...

for (String word : wordsWithLocation) {
   int nAppearances = 0;
   for (List<PositionInFile> positions :      
                            wordsWithLocation.get(word).values()) {
      nAppearances += positions.size();
   }
   System.out.println(word + " appears " + nAppearances + " times.");
}

但是我认为定义更简单,更清晰:

public class WordLocation {
   FileId fileId;
   PositionInFile position;

   ... 
}

然后只有一个Map<String, List<WordLocation>>。缺点是您没有这样的显式映射到文件。但是,信息仍然存在,List<WordLocation>甚至应该按照处理文件的顺序列出位置。

答案 1 :(得分:0)

假设您已按上述方式定义HashMap并添加如下条目:

HashMap<String, HashMap<Integer, ArrayList<Integer>>> outer = ...
HashMap<Integer, ArrayList<Integer>> inner = ...
inner.put(1, new ArrayList<Integer>());
outer.put("key1", inner);

您可以将ArrayList检索为:

ArrayList<Integer> arr = outer.get("key1").get(1);

答案 2 :(得分:0)

不确定。 但这是我用于Map的一般方式,其值为Collection类型。

Map<String, Collection<something>> map ...
for ... do some job
   if map.containsKey(keyFound) {
      map.get(foundKey).add(foundValue);
   } else {
      Collection <- create collection
      Collection.add(foundValue);
      map.put(foundKey, collection)
   }

您还可以查看Google Guava多地图。

希望有帮助...

答案 3 :(得分:0)

嵌套地图可行。但是我会为此创建一个类,即

class WordsInFile{

String fileName;
Map<String, List<Integer>> wordIdxMap;

}

这实际上与嵌套映射没有太大区别。但更具可读性,你可以添加像findWord(...)这样的方法,以避免因调用两次map的get(object)方法而迷路。它让你知道你将要得到什么。

我不知道这是不是一个好主意......