java hashmap is遍历_关于内存:在Java(或Scala)中遍历HashMap的HashMap

我创建了一个类Foo,该类具有返回Array的方法toArray()。

现在,我有一个将字符串映射到HashMaps的HashMap,后者将对象映射到Foo。那是:

HashMap>

我想创建一个新的类型的对象:

HashMap>>

这是通过为原始HashMAp中的每个元素Foo调用函数toArray()获得的。

为此,我通常会执行以下操作:

public static HashMap>> changeMap(Map mpOld) {

Object key2;

String key1;

Iterator it2;

HashMap>> mpNew=

new HashMap>>()

Iterator it1 = mpOld.keySet().iterator();

while (it1.hasNext()) {

key1=it1.next();

it2= mpOld.get(key1).keySet().iterator();

mpNew.put(key1,new HashMap>())

while (it2.hasNext()) {

key2=it2.next();

mpNew.get(key1).put(key2,mpOld.get(key1).get(key2).toArray());

//TODO clear entry mpOld.get(key1).get(key2)

}

//TODO clear entry mpOld.get(key1)

}

return mpNew;

}

类似的代码也可以,但是HashMap的大小太大,无法将其中的两个保存在内存中。如您所见,我在要清除某些条目的地方添加了两点。问题是,如果这样做,我会遇到并发错误,或者迭代器循环刚刚终止。

我想知道是否有更好的方法来遍历地图并复制信息。

另外,我正在一个Scala项目中工作,但是在这里我必须使用Java类型解决一些兼容性问题。尽管Java.util.HashMap不是迭代器,但Scala可能具有一些隐藏的功能来处理此问题?

谢谢,

迭代器提供了remove(..)方法,可以安全地删除以前访问的项目。遍历地图的键/值条目,将其转换并将其添加到新的地图中,并在使用时删除旧的。

/**

* Transfers and converts all entries from map1 to

* map2.  Specifically, the {@link Foo} objects of the

* inner maps will be converted to integer arrays via {@link Foo#toArray}.

*

* @param map1 Map to be emptied.

* @param map2 Receptacle for the converted entries.

*/

private static void transfer(Map> map1

, Map> map2) {

final Iterator>> mapIt

= map1.entrySet().iterator();

while (mapIt.hasNext()) {

final Entry> mapEntry = mapIt.next();

mapIt.remove();

final Map submap = new HashMap();

map2.put(mapEntry.getKey(), submap);

final Iterator> fooIt

= mapEntry.getValue().entrySet().iterator();

while (fooIt.hasNext()) {

final Entry fooEntry = fooIt.next();

fooIt.remove();

submap.put(fooEntry.getKey(), fooEntry.getValue().toArray());

}

}

}

我没有时间检查它,但是我猜类似的事情应该可以在scala Maps上工作(假设您使用的scala 2.8终于在这里了):

mpO.mapValues(_.mapValues(_.toArray))

它将使用您的外部映射,并用新的内部映射"替换"所有内部映射,其中值是Int数组。键和地图的一般"结构"保持不变。根据scaladoc的说法,"生成的地图将包裹原始地图,而不会复制任何元素。",因此它不会真正替代。

如果您还做一个

import scala.collection.JavaConversions._

那么可以使用与Scala映射相同的方式使用Java映射:JavaConversions包含一堆可以在scala和Java集合之间转换的隐式方法。

BTW最后使用Map >>可能并不真正方便,如果我是我,我会考虑引入一些隐藏此构造复杂性的类。

编辑以反映您的评论

import scala.collection.JavaConversions._

import java.util.Collections._

object MapValues {

def main(args: Array[String]) {

val jMap = singletonMap("a",singletonMap("b", 1))

println(jMap)

println(jMap.mapValues(_.mapValues(_+1)))

}

}

打印:

{A = {B = 1}}

地图(a->地图(b-> 2))

表明隐式函数很好地应用于了外部和内部映射。这是JavaConversions对象的目的:即使您有Java集合,也可以将其用作类似的scala类(具有增强的功能)。

您无需执行其他任何操作,只需导入JavaConversions。_

谢谢,但是尽管我在项目中使用Scala,但HashMaps是Java HashMaps,因此您不能在它们上调用mapVAlues。 这是使用JavaConversions解决此问题的一种方法吗?

您能解决您的问题吗? 我的编辑有帮助吗?

例如考虑字符串键;让我们调用输入数据:Map> data

for (Entry> entry : data.entrySet()) {

String itemKey = entry.getKey();

for (Entry innerEntry : entry.getValue().entrySet()) {

String innerKey = innerEntry.getKey();

Object o = innerEntry.getValue();

// whatever, here you have itemKey, innerKey and o

}

}

The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation), the results of the iteration are undefined. The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations.

为什么不在迭代器上调用remove ()方法,或者为什么不调用set.remove (iterator.next ()),其中iterator.next ()返回键,则set是键集,并对其迭代器进行迭代。

PS:还要尝试重构您的数据结构,也许是一些处理数据检索的中间类?包含数组作为值的映射中的映射什么也没说,很难跟踪。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值