我有这个功能:
public void insert( String token, int docID)
{
insertNormIdx( token, docID);
}
由主程序连续调用。 docID是一个文档的ID,令牌是我们在文档中找到的一个词。
所以这个函数被多次调用,直到所有文档都被解析。我想要做的是创建一个具有一个条目docID的散列图,这应该指向另一个散列图,其中包含我们在文档中找到的单词(标记)及其计数。
即,如果我们在文档(docID)'5'中找到单词(token)''10次',我想要一个包含这些信息的结构,如:5,the,10。
这就是我所做的,但它不起作用,只保留文件中的第一个字:
HashMap<Integer, HashMap<String, Integer>> normal_idx = new HashMap<Integer, HashMap<String, Integer>>();
public void insertNormIdx(String token, int docID)
{
HashMap<String, Integer> val = new HashMap<String, Integer>();
if(!normal_idx.containsKey(docID))
{
val.put(token, 1);
normal_idx.put(docID, val);
}
if (normal_idx.containsKey(docID))
{
if (normal_idx.get(docID).get(token)!=null)
{
val.put(token, normal_idx.get(docID).get(token)+1);
normal_idx.put(docID, val);
}
}
}
答案 0 :(得分:2)
您的代码中存在大量冗余和错误。您问题中的具体问题是因为此else
没有if
:
if (normal_idx.get(docID).get(token)!=null)
因此永远不会插入新的令牌。
但整个代码可以得到显着改善。在Java 8中,您可以使用以下命令替换整个方法:
normal_idx.computeIfAbsent(docID, k -> new HashMap<>())
.merge(token, 1, Integer::sum);
如果您使用的是早期的Java版本,可以试试这个:
HashMap<String, Integer> val = normal_idx.get(docID);
if (val == null) {
val = new HashMap<String, Integer>();
normal_idx.put(docID, val);
}
Integer count = val.get(token);
if (count == null) {
val.put(token, 1);
} else {
val.put(token, count + 1);
}
答案 1 :(得分:1)
更好的方法:
public void insertNormIdx(String token, int docID) {
Map<String, Integer> doc = normal_idx.get(docId);
if (doc == null) {
normal_idx.put(docId, doc = new HashMap<String, Integer>());
}
Integer counter = doc.get(token);
if (counter == null)
doc.put(token, 1);
else
doc.put(token, ++counter);
}
顺便说一下,不要只使用裸HashMap,创建类Document
。
答案 2 :(得分:1)
您可以使用Java 8的computeIfAbsent
方法在地图中放置/合并值,例如:
public void insertNormIdx(String token, int docID) {
normal_idx.computeIfAbsent(docID, k -> new HashMap<>()).merge(token, 1, (old, one) -> old + one);
}