【发布时间】:2017-05-04 15:34:26
【问题描述】:
我遇到了一个场景,我想将 HashMap 的所有键都小写(不要问为什么,我只需要这样做)。 HashMap 有几百万个条目。
起初,我以为我只是创建一个新地图,遍历要小写的地图条目,然后添加相应的值。这个任务应该每天只运行一次或类似的东西,所以我想我可以忍受这个。
Map<String, Long> lowerCaseMap = new HashMap<>(myMap.size());
for (Map.Entry<String, Long> entry : myMap.entrySet()) {
lowerCaseMap.put(entry.getKey().toLowerCase(), entry.getValue());
}
然而,当我的服务器在我即将复制地图的这段时间超载时,这会导致一些 OutOfMemory 错误。
现在我的问题是,我怎样才能以最小的内存占用完成这项任务?
是否会在小写后删除每个键 - 添加到新的地图帮助中?
我可以利用 java8 流来加快速度吗? (例如这样的)
Map<String, Long> lowerCaseMap = myMap.entrySet().parallelStream().collect(Collectors.toMap(entry -> entry.getKey().toLowerCase(), Map.Entry::getValue));
更新
好像是Collections.unmodifiableMap 所以我没有选择
小写后删除每个键 - 添加到新地图
【问题讨论】:
-
你不能一开始就插入小写的键吗?
-
您尝试做的事情很危险,因为在原始的
Map中可能有key和Key。那么你的地图应该如何表现呢? -
a) 不,这不太可能从并行处理中受益,b) 并行处理不能解决您的内存问题,c) 因为您自己已经回答了
remove选项,所以只有一个解决方案:增加更多的堆内存。 -
@sestus:不,这将不会从并行处理中受益。解释原因将超出此问题的范围。基本上,标准的
toMap收集器必须合并部分结果,合并成本与任何节省一样高。String.toLowerCase()操作太便宜了,无法补偿开销。 -
我真的,真的认为你应该告诉我们你想这样做的原因。这可能是“我的指甲太长所以我不得不剪掉我的手(不要问我为什么必须这样做)”的情况。也许有比将不可修改的映射键小写更好的解决方案。
标签: java hashmap java-8 java-stream