将项添加到复杂的数据结构`Map <string,map <string,string =“”>&gt;`

时间:2015-04-29 04:21:06

标签: java data-structures

我有以下复杂的数据结构:

Map<String, Map<String,String>> URL_and_entities = new HashMap<String, Map<String,String>>();

在循环内部我最终想要填充它,但我无法弄清楚如何。

这是我的代码,它本质上是一系列嵌套循环,它们发出HTTP请求以确定它们是否共享一个关系,这是由url的存在(或不存在)所揭示的。我试图保存URL(如果存在),以及引发它的两个实体:

for (String entity_1 : Q_value_references_for_sentence_entities) 
{

  for (String entity_2 : Q_value_references_for_sentence_entities) 
  {

        String URL_czech = "http://milenio.dcc.uchile.cl/sparql?default-graph-uri=&query=PREFIX+%3A+%3Chttp%3A%2F%2Fwww.wikidata.org%2Fentity%2F%3E%0D%0ASELECT+*+WHERE+%7B%0D%0A+++%3A" 
                           + entity_1 + "+%3FsimpleProperty+%3A" 
                           + entity_2 + "%0D%0A%7D%0D%0A&format=text%2Fhtml&timeout=0&debug=on";

        URL wikidata_page = new URL(URL_czech);
        HttpURLConnection wiki_connection = (HttpURLConnection)wikidata_page.openConnection();
        InputStream wikiInputStream = null;

        try 
        {
            // try to connect and use the input stream
            wiki_connection.connect();
            wikiInputStream = wiki_connection.getInputStream();
        } 
        catch(IOException error) 
        {
            // failed, try using the error stream
            wikiInputStream = wiki_connection.getErrorStream();
        }
        // parse the input stream using Jsoup
        Document docx = Jsoup.parse(wikiInputStream, null, wikidata_page.getProtocol()+"://"+wikidata_page.getHost()+"/");


        Elements link_text = docx.select("table.sparql > tbody > tr:nth-child(2) > td > a");
        //link_text.text();
        for (Element l : link_text) 
        {
            String output = l.text();
            output = output.substring(0, output.length()-1);
            list_of_relation_URLs.add( output );

            URL_and_entities.put( output , (entity_1, entity_2));
        }
    }           
}

我没有选择使用那个疯狂的谷歌数据库库,我之前使用过它,但在这种情况下,我无法看到一个令人信服的理由,为什么它会是优于Map<String, Map<String,String>>

更新

我无法获得价值。这似乎不起作用

String first__english_lang_Q = retrieved_entities.getKey();
String second_english_lang_Q = retrieved_entities.getValue();

System.out.println("`(" + value + ")'" + "`( " + entity_1 + ", " + entity_2 + ")'");

3 个答案:

答案 0 :(得分:0)

你只需要一个元组,你可以使用apache common Pair

Map<String, Pair<String,String>> URL_and_entities = new HashMap<String, Pair<String,String>>();

URL_and_entities.put("something", Pair.of("left", "right"))
URL_and_entities.get("something").getLeft();
URL_and_entities.get("something").getRight();

答案 1 :(得分:0)

试试这个:

Map<String,String> entities; 

for (String entity_1 : Q_value_references_for_sentence_entities) 
{
   for (String entity_2 : Q_value_references_for_sentence_entities) 
    {
       entities = new HashMap<String, String>();
       entities.put(entity_1, entity_2);

       ...check that URL exist and doesn't return null, and then convert it to a String...

       URL_and_entities.put(output, entities);
       }
    }
}

我不明白,为什么你使用Map来存储这两个实体。除非您计划使用一个实体来引用第二个实体,否则您可以简单地将两个实体存储在一个简单的数组中(或者技术上甚至是ArrayList或HashSet会比Map更好)。

只是做:

Map<String, String[]> URL_and_entities = new HashMap<String, String[]>();
String [] entities = new String[2];

for (String entity_1 : Q_value_references_for_sentence_entities) 
{
   for (String entity_2 : Q_value_references_for_sentence_entities) 
    {
       entities[0] = entity_1;
       entities[1] = entity_2;

       ...check that URL exist and doesn't return null, and then convert it to a String...

       URL_and_entities.put(output, entities);
       }
    }
}

然后检索并打印您刚刚执行的集合中的所有值:

   for (String url: byLetter.keySet()) {
        String [] retrievedValues = URL_and_entities.get(url);
        System.out.println(url + " " + retrievedValues[0] + ", " + retrievedValues[1];
    }

如果使用ArrayList,请执行:

   for (String url: byLetter.keySet()) {
        ArrayList retrievedValues = URL_and_entities.get(url);
        System.out.println(url + " " + retrievedValues.get(0) + ", " + retrievedValues.get(1);
    }

答案 2 :(得分:-1)

如果你只想使用一对(比如你的例子)而不是整个地图,你可以使用Map.Entry而不是在每个循环中创建一个地图......

有些事情是这样的:

Map<String, Map.Entry> URL_and_entities = new HashMap<String, Map.Entry>>();

然后在你的循环中有这样的事情:

Map.Entry entry = new AbstractMap.SimpleEntry(entity_1, entity_2);
URL_and_entities.put(output,entry);

编辑(回答评论):

稍后您可以从地图中获取您的价值:

Map.Entry myEntry = URL_and_entities.get(output);

其中output是您的密钥,您也可以获得您的条目的关键值和价值:

myEntry.getKey();
myEntry.getValue();

更新(关于@ ajb的评论)

正如ajs所说,这不是最好的方法,另一种方法是为这对夫妇写一个类这样的课:

class MyCouple {
    private String entity1;
    private String entity2;

    public MyCouple(String entity1, String entity2) {
        this.entity1 = entity1;
        this.entity2 = entity2;
    }

    public String getEntity1() {
        return entity1;
    }

    public String getEntity2() {
        return entity2;
    }

    public void setEntity1(String entity1) {
        this.entity1 = entity1;
    }

    public void setEntity2(String entity2) {
        this.entity2 = entity2;
    }
}

并按照以下方式创建地图:

Map<String, MyCouple> URL_and_entities = new HashMap<String, MyCouple>();

并在每次迭代中将此实例作为您的地图的值,如下所示:

MyCouple myCouple = new MyCouple(entity_1,entity_2);
URL_and_entities.put(output,myCouple);

你可以使用get函数的值。