使用与HashSet对应的固定Key创建HashMap。 出发点

我的目标是创建一个以String作为键的hashmap,并将条目值作为字符串的HashSet。


OUTPUT

这就是输出现在的样子:

Hudson+(surname)=[Q2720681], Hudson,+Quebec=[Q141445], Hudson+(given+name)=[Q5928530], Hudson,+Colorado=[Q2272323], Hudson,+Illinois=[Q2672022], Hudson,+Indiana=[Q2710584], Hudson,+Ontario=[Q5928505], Hudson,+Buenos+Aires+Province=[Q10298710], Hudson,+Florida=[Q768903]] 

根据我的想法,它应该是这样的:

 [Hudson+(surname)=[Q2720681,Q141445,Q5928530,Q2272323,Q2672022]] 

目的是在Wikidata中存储特定名称,然后将与其相关的所有Q值消除歧义,例如:

这是“布什”的页面。

我希望布什成为关键,然后对于所有不同的出发点, Bush可能与维基数据的终端页面相关联的所有不同方式,我想存储相应的“Q值”,或者是唯一的阿尔法 – 数字标识符。

我实际上在做的是尝试从维基百科歧义消除不同的名称,值,然后在wikidata中查找与该值相关联的唯一字母数字标识符。

例如, Bush我们有:

 George HW Bush George W. Bush Jeb Bush Bush family Bush (surname) 

因此,Q值为:

乔治HW布什 (Q23505)

乔治W.布什 (Q207)

杰布·布什 (Q221997)

布什家族 (Q2743830)

布什 (Q1484464)

我的想法是数据结构应该按照以下方式解释

关键: Bush 入围集: Q23505, Q207, Q221997, Q2743830, Q1484464

但是我现在的代码并没有这样做。

它为每个名称和Q值创建一个单独的条目。 即

关键: Jeb Bush 入围集: Q221997

关键: George W. Bush 入围集: Q207

等等。

在我的github页面上可以看到所有它的荣耀的完整代码,但我也将在下面总结它。

这就是我用来为我的数据结构添加值的方法:

 // add Q values to their arrayList in the hash map at the index of the appropriate entity public static HashSet put_to_hash(String key, String value) { if (!q_valMap.containsKey(key)) { return q_valMap.put(key, new HashSet() ); } HashSet list = q_valMap.get(key); list.add(value); return q_valMap.put(key, list); } 

这是我获取内容的方式:

  while ((line_by_line = wiki_data_pagecontent.readLine()) != null) { // if we can determine it's a disambig page we need to send it off to get all // the possible senses in which it can be used. Pattern disambig_pattern = Pattern.compile("
Wikipedia disambiguation page
"); Matcher disambig_indicator = disambig_pattern.matcher(line_by_line); if (disambig_indicator.matches()) { //off to get the different usages Wikipedia_Disambig_Fetcher.all_possibilities( variable_entity ); } else { //get the Q value off the page by matching Pattern q_page_pattern = Pattern.compile("\\[edit\\]"); Matcher match_Q_component = q_page_pattern.matcher(line_by_line); if ( match_Q_component.matches() ) { String Q = match_Q_component.group(1); // 'Q' should be appended to an array, since each entity can hold multiple // Q values on that basis of disambig put_to_hash( variable_entity, Q ); } } }

这就是我处理消歧页面的方式:

 public static void all_possibilities( String variable_entity ) throws Exception { System.out.println("this is a disambig page"); //if it's a disambig page we know we can go right to the wikipedia //get it's normal wiki disambig page Document docx = Jsoup.connect( "https://en.wikipedia.org/wiki/" + variable_entity ).get(); //this can handle the less structured ones. Elements linx = docx.select( "p:contains(" + variable_entity + ") ~ ul a:eq(0)" ); for (Element linq : linx) { System.out.println(linq.text()); String linq_nospace = linq.text().replace(' ', '+'); Wikidata_Q_Reader.getQ( linq_nospace ); } } 

我想也许我可以传递Key值,但我真的不知道。 我有点卡住了。 也许有人可以看到我如何实现这个function。

我不清楚你的问题是什么不起作用,或者你是否看到了实际的错误。 但是,虽然您的基本数据结构思想( String to String Set HashMap )是合理的,但“添加”function中存在一个错误。

 public static HashSet put_to_hash(String key, String value) { if (!q_valMap.containsKey(key)) { return q_valMap.put(key, new HashSet() ); } HashSet list = q_valMap.get(key); list.add(value); return q_valMap.put(key, list); } 

在第一次看到一个键的情况下( if (!q_valMap.containsKey(key)) ),它会为该键生成一个新的HashSet ,但它在返回之前不会为它添加value 。 (并且返回的值是该键的旧值,因此它将为null。)因此,您将失去每个术语的一个Q值。

对于像这样的多层数据结构,我通常只是对中间结构的活动进行特殊情况,然后在单个代码路径中进行添加和返回。 我想这会解决它。 (我也将它valSet因为它是一个集合,而不是列表。并且不需要每次都将该集合重新添加到地图;它是一个引用类型,并在第一次遇到该密钥时添加。 )

 public static HashSet put_to_hash(String key, String value) { if (!q_valMap.containsKey(key)) { q_valMap.put(key, new HashSet()); } HashSet valSet = q_valMap.get(key); valSet.add(value); return valSet; } 

另请注意,您返回的Set是对该键的实时Set的引用,因此您需要注意在调用者中修改它,如果您正在执行multithreading,则会出现并发访问问题。

或者只使用Guava Multimap这样您就不必担心自己编写实现。