有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用与哈希集对应的固定键创建哈希映射。出发点

我的目标是创建一个hashmap,其中字符串作为键,条目值作为字符串的HashSet


输出

现在的输出是这样的:

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值,例如:

This是“布什”的页面

我希望Bush是关键,然后对于所有不同的出发点,所有Bush可能与Wikidata终端页面关联的不同方式,我希望存储相应的“Q值”,或唯一的字母数字标识符

我实际做的是从维基百科消歧中提取不同的名称和值,然后在wikidata中查找与该值关联的唯一字母数字标识符

例如,对于Bush,我们有:

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

相应地,Q值为:

George H. W. Bush(Q23505)

George W. Bush(第2007季度)

Jeb Bush(Q221997)

(问题2743830)

(Q1484464)

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

键:Bush 条目集:Q23505, Q207, Q221997, Q2743830, Q1484464

但是我现在的代码不能做到这一点

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

键: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值,但我真的不知道。我有点困了。也许有人可以看看我如何实现这个功能


共 (1) 个答案

  1. # 1 楼答案

    我不清楚你的问题是什么不起作用,或者你是否看到了实际的错误。但是,虽然您的基本数据结构思想(StringSet<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。(返回的值是该键的旧值,因此将为null。)所以每一项都会失去一个Q值

    对于这样的多层数据结构,我通常只对中间结构进行特例化,然后在单个代码路径中进行添加和返回。我想这会解决的。(我还将把它称为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是对该键的live Set的引用,因此在调用者中修改它时需要小心,如果执行多线程处理,则会出现并发访问问题

    或者只使用番石榴Multimap,这样您就不必担心自己编写实现了