【问题标题】:Compare Hashmap values which are store as List structure比较存储为 List 结构的 Hashmap 值
【发布时间】:2017-07-09 03:27:43
【问题描述】:

我有哈希图,它的键是字符串,值存储为列表。

Map<String,List<Integer>> posmap = new HashMap<>();

因为我在同一个键下有多个值。 因此,例如我有 4 个键和值是:

[1681, 3523]

[276, 489]

[1527, 2865]

[300]

我还有另一个 treeList 包含这些排序后的值。我想要做的是(并询问);

Iterator<Integer> itr=myTreeSet.iterator();
    while(itr.hasNext())
    {
        int check = itr.next();
        for(Object value : map2.entrySet())
        {
            //System.out.println("Value is :" + value);

        }
    }

我想用我的 Hashmap entrySet 来检查 itr,如果等于则返回 hashmap key。上面的代码将 entrySet 作为数组返回。简述如何检查itr属于hashmap的entrySet,属于哪个key。

我将 map1 和 map2 作为参数

static void game(Map map1, Map map2, Hero h, HashSet< Integer> hash)

对不起各位。我没有说清楚我想所以你很困惑。我首先在 main func 中定义这个映射:

Map<String, Enemy> enemymap = new HashMap<>();
Map<String,List<Integer>> posmap = new HashMap<>();

我也将它们填充到 main func 中。填写完后,我将它们发送到有问题的功能游戏中。 posmap 是 map2。所以我指的是posmap。很抱歉造成混乱。 func的完整代码。

static void game(Map map1, Map map2, Hero h, HashSet< Integer> hash)
{
    TreeSet<Integer> myTreeSet = new TreeSet<>(); // For sorting min to max-for alignment
    myTreeSet.addAll(myHashset);
    System.out.println(myTreeSet);
    String start = "Micheal started travel with" + " " + h.getHealth() + " " + "HP!";
    Iterator<Integer> itr=myTreeSet.iterator();
    while(itr.hasNext())
    {
        int check = itr.next();
        /* for(Map.Entry<String, List<Integer>> entry : map2.entrySet())
            {
                if(entry.getValue() != null && entry.getValue().contains(check))
                System.out.println("The key " + entry.getKey() + "contains the treeset value " + check);

            } -/
    }

}

从主函数发送为:

game(enemymap, posmap , hero, myHashset);

【问题讨论】:

  • 我不确定我是否理解这个问题,因为它太草率了。 posmap 是否应该与 map2 相同?但是,如果您想测试一个整数是否在映射中的值列表之一中,您需要查看所有值并使用类似List.contains 的内容。不要说Object value,说Map.Entry&lt;String,List&lt;Integer&gt;&gt; value。否则您将无法检索这些值。
  • 我认为您的澄清使事情变得不太清楚。此外,在参数列表中使用原始类型(如Map,而不是Map&lt;String,List&lt;Integer&gt;&gt;)将难以编写代码来做正确的事情,因为编译器不知道您的键是字符串而您的值是列表。

标签: java list arraylist data-structures hashmap


【解决方案1】:

我会推荐以下方法:

Iterator<Integer> itr=myTreeSet.iterator();
while(itr.hasNext())
{
    int check = itr.next();
    for(Map.Entry<String, List<Integer>> entry : map2.entrySet())
    {
        if(entry.getValue() != null && entry.getValue().contains(check))
        System.out.println("The key " + entry.getKey() + "contains the treeset value " + check);

    }
}

【讨论】:

  • 谢谢@ajb。感谢您的投入。刚刚修好了。
  • 它说 map2.entrySet:类型不匹配:无法从元素类型 Object 转换为 Map.Entry
  • 顺便说一下,我把map2作为参数。
  • @Lucas,map2 的类型是什么?不是您在问题中描述的Map&lt;String,List&lt;Integer&gt;&gt; 吗?
  • 是的。 Map> = new HashMap();
【解决方案2】:

由于您不记得在将 int 存储在 hashmap 中时使用的 hashkey,因此您需要检查 int 是否在散列的任何值中。

for(Map.Entry<String,List<Integer>>entry: map2.values()) {
    if( entry.getValue().contains(check) ) return entry.getKey();
}

类似的东西。

【讨论】:

    【解决方案3】:

    其他解决方案打印或返回单个键。根据您简短的原始帖子,我认为您想要一套,所以这就是我所做的。

    根据@ajb 的建议编辑:

    Set<Integer> myTreeSet = new TreeSet<>();
    Map<String,List<Integer>> posmap = new HashMap<>();
    Iterator<Integer> itr = myTreeSet.iterator();
    
    //The set of keys containing values in any list of posmap
    Set<String> matchedKeys = new HashSet<>();
    
    //Iterate through the TreeSet Integers
    itr.forEachRemaining(itrVal -> {
       //Stream each entry of the posmap
       posmap.entrySet().stream()
             //Remove the entries without the itrVal in the entry's list
             .filter(entry -> entry.getValue().contains(itrVal))
             //Add each key with a match to the set
             .forEach(matchedEntry -> matchedKeys.add(matchedEntry.getKey()));
    });
    
    return matchedKeys;
    

    如果您可以使用 Apache Commons,这可能是一个不错的方法:

    Set<Integer> myTreeSet = new TreeSet<>();
    Map<String,List<Integer>> posmap = new HashMap<>();
    Iterator<Integer> itr = myTreeSet.iterator();
    
    Set<String> matchedKeys = new HashSet<>();
    
    List<Integer> treeSetValues = IteratorUtils.toList(itr);
    
    treeSetValues.stream().map(val -> {
       return posmap.entrySet().stream()
             .filter(entry -> entry.getValue().contains(itrVal))
             .collect(Collectors.toSet());
    });
    
    return matchedKeys;
    

    如果你不能使用 IteratorUtils.toList(),你可以使用 Guava 和 Lists.newArrayList()。

    【讨论】:

    • 当我发布这个解决方案时,我认为 posmap 正在搜索树列表中的值。但是,您的问题中突然出现了 map2?
    • 我认为使用Map.Entry 更有效。您的方法检索所有键,然后查找每个键。当您从映射中检索所有键时,这些值应该随时可用,就在键旁边。但是您忽略了这些值,然后再次查找它们,这是在做双重工作。使用entrySet() 可以避免多余的工作。您的代码在我看来很好——这只是对如何改进它的建议。
    • 不不。 posmap 是实际值。 map2 是参数名称。Matt 评论的答案。
    • 我会尝试调整我的解决方案以使用您解释的@ajb 并在几秒钟内重新发布,谢谢!
    • @Lucas 那你为什么用粗体字母“我以 map1 作为参数名称”?现在你有两个地图参数,我们比以前更困惑了。
    猜你喜欢
    • 2018-10-31
    • 1970-01-01
    • 2021-12-13
    • 2011-12-11
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    相关资源
    最近更新 更多