【问题标题】:Get a list of key's in HashMap having key like 'some value'获取 HashMap 中具有“某个值”之类的键的键列表
【发布时间】:2014-06-01 12:04:42
【问题描述】:

在Mysql中我们可以查询一个有子句“WHERE name LIKE '%someName%'”的表,我们能不能和java中的HashMap有同样的功能,如果可以,我们怎样才能更有效地做到这一点在更短的时间内通过不迭代每个元素?

【问题讨论】:

  • 用一些正则表达式循环,或者创建你自己的地图实现
  • “名称”是地图中的键还是值?您要返回键或值列表吗?
  • "name" 是地图中的一个键
  • 您希望它的效率如何?您可以对 HashMap 进行暴力搜索,也可以有效地使用 NavigableMap,但代码要复杂得多。即,如果暴力搜索对您来说不是很明显,请不要尝试使用 NavigableMap。
  • 我需要更频繁地在大量key中搜索key

标签: java hashmap


【解决方案1】:

在 Java 中可能有实现此功能的方法,但 HashMap 不会这样做。

【讨论】:

  • 我也想要实现这个的方法,你能展示一些代码示例吗
【解决方案2】:

如果您想获取映射中与给定键关联的所有值,您正在执行反向查找

您需要遍历映射中的每个键/值对,搜索给定值并将其存储到集合中。像这样的:

List<KeyType> keys = new ArrayList<>();
for (Map.Entry<KeyType, ValueType> e : myMap)
    if(e.getValue().equals(valueWeAreSearchingFor)) keys.add(e.getKey());

【讨论】:

  • 当搜索一个经常有大约 1000 个键的地图时会发生什么?
  • 这可能不符合 OP 的需求,因为他想匹配一个模式,而不是一个精确的值。
  • @achuth 好吧,你必须遍历整个地图,所以它会。考虑使用类似BidiMap
  • @Joffrey 是的,我没有得到问题的那一部分。那么你的回答会更好,点赞。
【解决方案3】:

您可以迭代所有键并检查它们是否与正则表达式匹配。这可能不是最有效的方法,但这是我想到的第一件事。 这是它的样子:

Pattern p = Pattern.compile("*someName*"); // the regexp you want to match

List<String> matchingKeys = new ArrayList<>();
for (String key : map.keySet()) {
    if(p.matcher(key).matches()) {
        matchingKeys.add(key);
    }
}

// matchingKeys now contains the keys that match the regexp

注意:map 应该像这样提前声明:

HashMap<String, SomeValueClass> map = new HashMap<>();

【讨论】:

  • 这将满足我对功能的需求,但我正在考虑必须大量迭代的大量键值
  • @achuth 那为什么不使用真正的数据库呢?如果键的数量那么大,你的程序需要多少内存?
  • 实际上我从数据库表的列中获取所有键,大小为 62Kb
  • @achuth 那么为什么在获取信息时不使用LIKE SQL 关键字呢?我认为这将比将所有内容加载到内存中并连续多次迭代所有内容更有效。
  • 所有的key都以JSON格式存储在单行单列中
【解决方案4】:

如果您使用的是 Java SE 8 和新的 Streams API:我认为有一个 filter 方法基本上就是您要寻找的方法。

例如类似(未经测试!):

myMap.entrySet().stream().filter(entry -> entry.getKey().contains("someName")).map(entry -> entry.getValue()).collect(Collectors.toList());

【讨论】:

  • 谢谢@Puce!我只需要关键部分,所以myMap.entrySet().stream().filter(entry -&gt; entry.getKey().contains("someName")).collect(Collectors.toList()); 就足够了
【解决方案5】:

删除所有不包含关键部分的值:

yourMap.keySet().removeIf(key -> !key.contains(keyPart));

或正则表达式:

yourMap.keySet().removeIf(key -> !key.matches(".*keyPart.*"));

【讨论】:

    猜你喜欢
    • 2011-11-15
    • 1970-01-01
    • 2012-05-17
    • 2016-03-09
    • 2019-01-01
    • 2014-07-26
    • 2014-12-01
    • 2013-01-18
    相关资源
    最近更新 更多