如何检查Map中的键是否以给定字符串值开头

17

我正在寻找类似这样的方法:

myMap.containsKeyStartingWith("abc"); // returns true if there's a key starting with "abc" e.g. "abcd"
或者
MapUtils.containsKeyStartingWith(myMap, "abc"); // same

我想知道是否有简单的方法来做到这一点。

谢谢

3个回答

17

这可以使用标准的SortedMap来完成:

Map<String,V> tailMap = myMap.tailMap(prefix);
boolean result = (!tailMap.isEmpty() && tailMap.firstKey().startsWith(prefix));

未排序的映射(例如 HashMap)本质上不支持前缀查找,因此对于这些映射,您必须遍历所有键。


1
由于我正在使用哈希映射,我可以通过以下方式创建树映射:TreeMap treeMap = new TreeMap(); treeMap.putAll(hashMap); - Edd
4
甚至更简单的方式是 TreeMap<K,V> treeMap = new TreeMap<K,V>(hashMap);,其中 hashMap 是原始的哈希映射。 - NPE

3

从地图中,您可以获取一组键,如果它们是字符串,则可以迭代集合元素并检查 startsWith("abc")


谢谢,我可以看到这会起作用,尽管我希望不必迭代键集。 - Edd
@Edd 为什么不呢?这是由Java开发人员进行了优化,以此方式使用;) - Adel Boutros
除非将其提取到单独的方法中,否则它会导致更高的圈复杂度。我没有明显的类可以放置这样的方法,所以我希望不需要为具有单个方法的地图创建新的实用程序类...听起来像是我在偷懒,但如果恰好有现成的实用程序方法,那将会很有帮助...但这只是一厢情愿的想法 ;) - Edd
迭代地遍历映射键的效率较低:它是O(N)。排序后的映射可以做得更好:O(log N)。 - Martin Ellis
@martiell 但他没有指明他使用的是哪种地图。 - Adel Boutros
@AdelBoutros 当然,但它也没有说明他在地图上进行了哪些其他操作。在没有上下文的情况下,我们无法确定更改数据结构是否有意义。 - Martin Ellis

0
为了进一步完善Adel Boutros有关迭代键效率的答案/评论,您可以将键迭代封装在一个Map子类或装饰器中。
扩展HashMap将为您提供一个类来放置该方法,并将特定于映射的代码排除在您的方法之外,从而降低复杂性并使代码更加自然易读。

这意味着我的HashMap需要是扩展HashMap的实例,我必须执行从Map(如果map声明为Map)到使用该方法的转换。它确实将代码放在一个整洁的位置,但可能不太可用。 - Edd
是的。或者你可以使用 MyMapExtension m = new MyMapExtension(myMap); 这种方式。或者你可以采用装饰器模式来包装地图。两种方法都与你最初的想法类似。 - David Carboni
我明白了...我想修饰器选项将防止创建地图的新实例,因此应该更有效。 - Edd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接