使用与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(" "); 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
这样您就不必担心自己编写实现。