Java:在 HashMap 中使用 ArrayList,字符串为键

Posted

技术标签:

【中文标题】Java:在 HashMap 中使用 ArrayList,字符串为键【英文标题】:Java: using ArrayList in HashMap with String as key 【发布时间】:2012-10-26 19:00:24 【问题描述】:

我没有看到我的错误在这里,我得到的是一个包含以下值的字符串数组,逐行:

San Jose -> San Francisco
San Jose -> Anchorage
New York -> Anchorage
New York -> San Jose
New York -> San Francisco
New York -> Honolulu
Anchorage -> New York
Anchorage -> San Jose
Honolulu -> New York
Honolulu -> San Francisco
Denver -> San Jose
San Francisco -> New York
San Francisco -> Honolulu
San Francisco -> Denver

我想将这些值放在一个 HashMap 中,使用右侧的字符串作为键,并将值设为 ArrayList,这样如果我询问“San Jose”的目的地,它将遍历列表并返回“旧金山”和“安克雷奇”。我还没有设法让键值关系正常工作。方法完成运行时的原因。对于任何城市,该值将是其最后一次迭代的值,(旧金山)返回纽约、檀香山和丹佛的所有键。

    private void createDataBase()
   
    ArrayList<String> tempValues = new ArrayList <String>();
    for (int i = 0; i < database.size();i++) 
    
        String line = database.get(i);
        //String value = "";  
        if (line.length() > 1)
        
            int keyStart = 0;
            int keyEnd = line.indexOf("-");

            int valueStart = keyEnd+3;
            int valueEnd = line.length();

            String key = line.substring(keyStart, keyEnd);
            String value = line.substring(valueStart, valueEnd);
            tempValues.add(value);
            System.out.println(keyValueDatabase.toString());
            keyValueDatabase.put(key, tempValues);

        
        else 
        
            tempValues.clear();
        

    
    System.out.println(keyValueDatabase.toString());

【问题讨论】:

与您的问题无关,但如果相同的目的地应该只出现一次,您也可以使用 Set 来保证这一点:如果您希望目的地始终排序,则为 TreeSet,如果您想以原始方式迭代它们,则为 LinkedHashSet顺序,否则为 HashSet。 【参考方案1】:

除非您无法使用外部库,否则您可能需要考虑MultiValueMap

【讨论】:

【参考方案2】:

这是另一个值得关注的值:

我想您可以检查“keyValueDatabase”映射以查看该键是否已在映射中,如果它不存在,则添加一个新列表作为值,如果它确实抓取了该列表并再添加一个项目。

private void createDataBase()

    for (int i = 0; i < database.size();i++) 
    
    String line = database.get(i);
    //String value = ""; 
    if (line.length() > 1)
    
        int keyStart = 0;
        int keyEnd = line.indexOf("-");

        int valueStart = keyEnd+3;
        int valueEnd = line.length();

        String key = line.substring(keyStart, keyEnd);
        String value = line.substring(valueStart, valueEnd);
        tempValues.add(value);
        System.out.println(keyValueDatabase.toString());

        //Check if the map already contains an entry for the key
        if(keyValueDatabase.containsKey(key))
        
        //If yes, grab the value and add one to the list
        ArrayList<String> tempValues = keyValueDatabase.get(key);
        tempValues.add(value); //this should get updated in the same list due to reference
        
        else
           ArrayList<String> tempValues = new ArrayList <String>();
        tempValues.add(value);
        keyValueDatabase.put(key, tempValues);
                                
    
    
    System.out.println(keyValueDatabase.toString());

【讨论】:

我更喜欢我的回答方式,因为它只会对现有项目进行一次地图查找,并且如果地图碰巧包含空值(尽管这里不是这种情况),它也可以工作。 @hyde:是的,你是对的。您的方式将导致更少的地图查找...谢谢!【参考方案3】:

你的这段代码是错误的:

tempValues.add(value);
System.out.println(keyValueDatabase.toString());
keyValueDatabase.put(key, tempValues);

您需要执行以下操作,而不是上面的部分:

List<String> values = keyValueDatabase.get(key);
if (values == null) 
   values = new ArrayList <String>();
   keyValueDatabase.put(key, values);

values.add(value);

...并删除tempValues

【讨论】:

以上是关于Java:在 HashMap 中使用 ArrayList,字符串为键的主要内容,如果未能解决你的问题,请参考以下文章

Java操作excel(POI)

什么时候在java中使用linkedhashmap而不是hashmap?

在 Java 8 中使用 Lambda 对 ArrayList 进行排序

在 Java 中遍历 HashMap 的5种最佳方式

理解Java中HashMap的工作原理

面试专题 HashMap如何在Java中工作