java - 迭代 HashMap 的键范围

标签 java hashmap iteration

是否可以迭代HashMap中特定范围的键?

我的 HashMap 包含键值对,其中键表示 Excel 中的某个行列(例如 "BM""AT"),值是该单元格中的值。

例如,我的表导入是:

startH = {
   BQ=2019-11-04, 
   BU=2019-12-02, 
   BZ=2020-01-06, 
   CD=2020-02-03, 
   CH=2020-03-02, 
   CM=2020-04-06
}  

endH = {
   BT=2019-11-25, 
   BY=2019-12-30, 
   CC=2020-01-27, 
   CG=2020-02-24, 
   CL=2020-03-30, 
   CP=2020-04-27
}

我需要使用键范围迭代这两个 HashMap ,以便以正确的顺序提取数据。例如从“BQ”“BT”

最佳答案

说明

Is it possible to iterate over hashmap but using its index?

没有。

HashMap没有索引。根据底层的实现,这也是不可能的。 Java HashMap 不一定由哈希表表示。它可以切换到红黑树,并且它们根本不提供直接访问。所以不,不可能。

这种方法还有另一个根本缺陷。 HashMap 不维护任何顺序。迭代它会产生随机顺序,每次启动程序时这些顺序都会改变。但对于这种方法,您需要插入顺序。幸运的是,LinkedHashMap 可以做到这一点。但它仍然不提供基于索引的访问。

<小时/>

解决方案

一代

但是,您实际上甚至不需要基于索引的访问。您想要检索某个键范围,例如从 "BA""BM"。使用 HashMap 的一个好方法是生成键范围并简单地使用 Map#get 检索数据:

char row = 'B';
char columnStart = 'A';
char columnEnd = 'M';

for (char column = columnStart; columnStart <= columnEnd; column++) {
    String key = Chararcter.toString(row) + column;
    String data = map.get(key);
    ...
}

如果您需要适当的边缘情况处理,例如环绕字母表(使用 'A' + (column % AlphabetSize)),您可能需要对其进行一些微调,也许它需要一些对于添加,charint 转换,反之亦然,未测试。

导航 map

实际上有一种 map 变体,可以提供几乎您想要的开箱即用的功能。但与简单的 HashMap 相比,性能成本更高。该接口(interface)称为NavigableMap。 TreeMap 类是一个很好的实现。问题是它需要明确的命令。不过,好处是您实际上需要 String 的自然顺序,即字典顺序。

因此,您只需将其与现有数据一起使用,然后使用方法NavigableMap#subMap:

NavigableMap<String, String> map = new TreeMap<>(...);
String startKey = "BA";
String endKey = "BM";

Map<String, String> subMap = map.subMap(startKey, endKey);
for (Entry<String, String> entry : subMap.entrySet()) {
    ...
}

如果您必须多次执行此类请求,这肯定会有所返回,并且它是此用例的完美数据结构。

链接迭代

如前所述,也可以(尽管效率不高)使用 LinkedHashMap (以维护插入顺序),然​​后简单地迭代键范围。但这有一些主要缺点,例如,它首先需要通过完全迭代到范围的起点来定位该范围的起点。它依赖于您是否正确插入它们。

LinkedHashMap<String, String> map = ...
String startKey = "BA";
String endKey = "BM";

boolean isInRange = false;
for (Entry<String, String> entry : map.entrySet()) {
    String key = entry.getKey();
    if (!isInRange) {
        if (key.equals(startKey)) {
            isInRange = true;
        } else {
            continue;
        }
    }

    ...

    if (key.equals(endKey)) {
        break;
    }
}

关于java - 迭代 HashMap 的键范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58947891/

相关文章:

javascript - for 循环迭代的替代方案如何工作? (Javascript)

java - 使用静态常量保存 Android 应用程序状态

java - Jboss - 最大上传文件

java - 在jsp中获取struts.xml Action 名称

java - Map 的值是一个对象。我如何使用/迭代所有这些变量? ( java )

Java 反转映射

python - Julia 集分形

java - 处理具有多个按钮/帖子的表单

java - HashSet 和 HashMap 上 contains 方法的一致性

C++迭代扩展容器