创建一个HashMap,固定的Key对应一个HashSet。出发点
Create a HashMap with a fixed Key corresponding to a HashSet. point of departure
我的目标是创建一个以字符串为键、条目值为字符串的哈希集的哈希图。
输出
这是现在的输出:
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]]
目的是在维基数据中存储一个特定的名称,然后所有与其相关的 Q 值是消歧的,例如:
This 是 "Bush" 的页面。
我希望 Bush 成为关键,然后对于所有不同的出发点,Bush
可以与维基数据终端页面相关联的所有不同方式,我想存储相应的 "Q value" 或唯一的字母数字标识符。
我实际上在做的是尝试从维基百科消歧中抓取不同的名称、值,然后在维基数据中查找与该值关联的唯一字母数字标识符。
例如,Bush
我们有:
George H. W. Bush
George W. Bush
Jeb Bush
Bush family
Bush (surname)
相应Q值为:
George H. W. Bush (Q23505)
George W. Bush (Q207)
Jeb Bush (Q221997)
Bush family (Q2743830)
Bush (Q1484464)
我的想法是数据结构应该这样解释
键:Bush
条目集: Q23505, Q207, Q221997, Q2743830, Q1484464
但我现在拥有的代码无法做到这一点。
它为每个名称和 Q 值创建一个单独的条目。即
键:Jeb Bush
条目集: Q221997
键:George W. Bush
条目集: Q207
等等。
可以在 my github page 上看到完整的代码,但我也会在下面对其进行总结。
这就是我用来向我的数据结构添加值的方法:
// add Q values to their arrayList in the hash map at the index of the appropriate entity
public static HashSet<String> put_to_hash(String key, String value)
{
if (!q_valMap.containsKey(key))
{
return q_valMap.put(key, new HashSet<String>() );
}
HashSet<String> 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("<div class=\"wikibase-entitytermsview-heading-description \">Wikipedia disambiguation page</div>");
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("<!-- wikibase-toolbar --><span class=\"wikibase-toolbar-container\"><span class=\"wikibase-toolbar-item " +
"wikibase-toolbar \">\[<span class=\"wikibase-toolbar-item wikibase-toolbar-button wikibase-toolbar-button-edit\"><a " +
"href=\"/wiki/Special:SetSiteLink/(.*?)\">edit</a></span>\]</span></span>");
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
值,但我真的不知道。我有点卡住了。也许有人可以看到我如何实现这个功能。
我不清楚你的问题是什么不起作用,或者你是否看到了实际的错误。但是,虽然您的基本数据结构想法(String
到 Set<String>
的 HashMap
)是合理的,但 "add" 函数中存在错误。
public static HashSet<String> put_to_hash(String key, String value)
{
if (!q_valMap.containsKey(key))
{
return q_valMap.put(key, new HashSet<String>() );
}
HashSet<String> list = q_valMap.get(key);
list.add(value);
return q_valMap.put(key, list);
}
在第一次看到某个键的情况下 (if (!q_valMap.containsKey(key))
),它会为该键激活一个新的 HashSet
,但不会将 value
添加到它在 returning 之前。 (并且 returned 值是该键的旧值,因此它将为空。)因此您将丢失每个术语的 Q 值之一。
对于像这样的多层数据结构,我通常只对中间结构进行特殊处理,然后在单个代码路径中进行添加和 return。我认为这会解决它。 (我也将其称为 valSet
,因为它是一个集合而不是列表。并且无需每次都将集合重新添加到地图;它是一个引用类型,并且会在您第一次添加时添加遇到那把钥匙。)
public static HashSet<String> put_to_hash(String key, String value)
{
if (!q_valMap.containsKey(key)) {
q_valMap.put(key, new HashSet<String>());
}
HashSet<String> valSet = q_valMap.get(key);
valSet.add(value);
return valSet;
}
还要注意 Set
你 return 是对那个键的实时 Set
的引用,所以你需要小心在调用者中修改它,如果你正在做多线程你会遇到并发访问问题。
或者只使用 Guava Multimap
这样您就不必担心自己编写实现了。
我的目标是创建一个以字符串为键、条目值为字符串的哈希集的哈希图。
输出
这是现在的输出:
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]]
目的是在维基数据中存储一个特定的名称,然后所有与其相关的 Q 值是消歧的,例如:
This 是 "Bush" 的页面。
我希望 Bush 成为关键,然后对于所有不同的出发点,Bush
可以与维基数据终端页面相关联的所有不同方式,我想存储相应的 "Q value" 或唯一的字母数字标识符。
我实际上在做的是尝试从维基百科消歧中抓取不同的名称、值,然后在维基数据中查找与该值关联的唯一字母数字标识符。
例如,Bush
我们有:
George H. W. Bush
George W. Bush
Jeb Bush
Bush family
Bush (surname)
相应Q值为:
George H. W. Bush (Q23505)
George W. Bush (Q207)
Jeb Bush (Q221997)
Bush family (Q2743830)
Bush (Q1484464)
我的想法是数据结构应该这样解释
键:Bush
条目集: Q23505, Q207, Q221997, Q2743830, Q1484464
但我现在拥有的代码无法做到这一点。
它为每个名称和 Q 值创建一个单独的条目。即
键:Jeb Bush
条目集: Q221997
键:George W. Bush
条目集: Q207
等等。
可以在 my github page 上看到完整的代码,但我也会在下面对其进行总结。
这就是我用来向我的数据结构添加值的方法:
// add Q values to their arrayList in the hash map at the index of the appropriate entity
public static HashSet<String> put_to_hash(String key, String value)
{
if (!q_valMap.containsKey(key))
{
return q_valMap.put(key, new HashSet<String>() );
}
HashSet<String> 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("<div class=\"wikibase-entitytermsview-heading-description \">Wikipedia disambiguation page</div>");
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("<!-- wikibase-toolbar --><span class=\"wikibase-toolbar-container\"><span class=\"wikibase-toolbar-item " +
"wikibase-toolbar \">\[<span class=\"wikibase-toolbar-item wikibase-toolbar-button wikibase-toolbar-button-edit\"><a " +
"href=\"/wiki/Special:SetSiteLink/(.*?)\">edit</a></span>\]</span></span>");
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
值,但我真的不知道。我有点卡住了。也许有人可以看到我如何实现这个功能。
我不清楚你的问题是什么不起作用,或者你是否看到了实际的错误。但是,虽然您的基本数据结构想法(String
到 Set<String>
的 HashMap
)是合理的,但 "add" 函数中存在错误。
public static HashSet<String> put_to_hash(String key, String value)
{
if (!q_valMap.containsKey(key))
{
return q_valMap.put(key, new HashSet<String>() );
}
HashSet<String> list = q_valMap.get(key);
list.add(value);
return q_valMap.put(key, list);
}
在第一次看到某个键的情况下 (if (!q_valMap.containsKey(key))
),它会为该键激活一个新的 HashSet
,但不会将 value
添加到它在 returning 之前。 (并且 returned 值是该键的旧值,因此它将为空。)因此您将丢失每个术语的 Q 值之一。
对于像这样的多层数据结构,我通常只对中间结构进行特殊处理,然后在单个代码路径中进行添加和 return。我认为这会解决它。 (我也将其称为 valSet
,因为它是一个集合而不是列表。并且无需每次都将集合重新添加到地图;它是一个引用类型,并且会在您第一次添加时添加遇到那把钥匙。)
public static HashSet<String> put_to_hash(String key, String value)
{
if (!q_valMap.containsKey(key)) {
q_valMap.put(key, new HashSet<String>());
}
HashSet<String> valSet = q_valMap.get(key);
valSet.add(value);
return valSet;
}
还要注意 Set
你 return 是对那个键的实时 Set
的引用,所以你需要小心在调用者中修改它,如果你正在做多线程你会遇到并发访问问题。
或者只使用 Guava Multimap
这样您就不必担心自己编写实现了。