Java 迭代HashMap的键范围
是否可以从Java 迭代HashMap的键范围,java,hashmap,iteration,Java,Hashmap,Iteration,是否可以从HashMap迭代特定范围的键 My 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=
HashMap
迭代特定范围的键
My 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”
//rangeLower和rangeUpper可以是参数
int i=0;
for(对象映射键:map.keySet()){
如果(irangeUpper){
i++;
继续;
}
//用mapKey做些什么
}
上面的代码通过获取键集并显式维护索引并在每个循环中递增索引来进行迭代。另一种选择是使用
LinkedHashMap
,它维护了一个双链接列表,用于维护插入顺序。我认为您不能。您提出的算法假设HashMap的键是有序的,而不是有序的。密钥的顺序没有保证,只有关联本身才有保证
您可以将数据结构更改为以下内容:
ranges = {
BQ=BT,
BU=BY,
....
}
然后在HashMap键(开始单元格)上进行迭代,就可以很容易地找到匹配的结束单元格。解释
是否可以在hashmap上迭代,但使用其索引
没有
HashMap
没有索引。根据底层实现,这也是不可能的。JavaHashMap
s不一定由哈希表表示。它可以切换到红黑树,而它们根本不提供直接访问。所以不,不可能
这种方法还有一个根本缺陷<代码>哈希映射不维护任何顺序。迭代它会产生随机顺序,每次启动程序时都会发生变化。但对于这种方法,您需要插入顺序。幸运的是,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);
...
}
如果您必须不止一次地执行此类请求,这肯定会有回报,并且它是这个用例的完美数据结构
链接迭代
如前所述,也可以使用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;
}
}
LinkedHashMap=。。。
字符串startKey=“BA”;
字符串endKey=“BM”;
布尔值isInRange=false;
for(条目:map.entrySet()){
String key=entry.getKey();
如果(!isInRange){
if(键等于(开始键)){
isInRange=真;
}否则{
继续;
}
}
...
如果(键等于(结束键)){
打破
}
}
HashMap没有索引。根据底层实现,这也是不可能的。Java哈希映射不一定由哈希表表示。它可以切换到红黑树,而它们根本不提供直接访问。不,不可能,这是个XY问题。有更好的方法来解决您描述的问题。例如,使用LinkedHashMap
(记住插入顺序),然后简单地对其进行迭代。您也可以只生成所需范围内的键。例如,BA
到BM
,然后使用map.get
或潜在的NavigableMap
@chrylis onstrike简单访问数据-这是一个很好的建议,谢谢。我总是忘记这个未充分使用的界面:)将它添加到我的答案中。OP实际上不想按索引迭代,而是按excel的行/列范围迭代(例如,行B
从BA
到BM
),我重新阅读它是有意义的。如果OP愿意,我可以删除答案。除此之外,我甚至认为在非LinkedHashMap
上这样做毫无意义。既然顺序是随机的,就永远不应该依赖它。因此,在没有重大免责声明的情况下建议使用此代码段可能会很危险。感谢您提供此解决方案。我正在使用LinkedHashMap解决我的问题,现在它可能会出现。谢谢你编辑这个问题:)救了我一天,很高兴它能工作。请允许我问一下,您为什么使用这三种方法中的一种我从LinkedHashMap开始,它提供了预期的输出,后来您添加了NavigableMap。按照建议,我将尝试NavigableMap作为更好的方法。谢谢
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<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;
}
}