Sku*_*uge 6 java memory iterator scala hashmap
我创建了一个Foo具有toArray()返回方法的类Array<Int>.
现在,我有一个HashMap映射字符串到HashMaps,它将Objects映射到Foo.那是:
HashMap<String,HashMap<Object,Foo>>
Run Code Online (Sandbox Code Playgroud)
我想创建一个类型的新对象:
HashMap<String,HashMap<Object,Array<Int>>>
Run Code Online (Sandbox Code Playgroud)
这是通过为原始HashMAp中的每个元素Foo调用函数toArray()获得的.
为此,我通常会这样做:
public static HashMap<String,HashMap<Object,Array<Int>>> changeMap(Map mpOld) {
Object key2;
String key1;
Iterator it2;
HashMap<String,HashMap<Object,Array<Int>>> mpNew=
new HashMap<String,HashMap<Object,Array<Int>>>()
Iterator it1 = mpOld.keySet().iterator();
while (it1.hasNext()) {
key1=it1.next();
it2= mpOld.get(key1).keySet().iterator();
mpNew.put(key1,new HashMap<Object,Array<Int>>())
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;
}
Run Code Online (Sandbox Code Playgroud)
类似的代码工作正常,但HashMap的大小太大,无法在内存中保存其中两个.如你所见,我添加了两点,我想清除一些条目.问题是,如果我这样做,我会得到一个并发错误,或者迭代器循环只是终止.
我想知道是否有更好的方法来迭代地图并复制信息.
此外,我正在使用Scala项目,但在这里我必须使用Java类型来解决一些兼容性问题.虽然Java.util.HashMap不是迭代器,但也许Scala有一些隐藏的功能来处理这个问题?
谢谢,
迭代器提供remove(..)了安全删除以前访问过的项目的方法.迭代地图的键/值条目,转换它们并将它们添加到新地图中,并在移动时删除旧地图.
/**
* Transfers and converts all entries from <code>map1</code> to
* <code>map2</code>. 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<String, Map<Object, Foo>> map1
, Map<String, Map<Object, int[]>> map2) {
final Iterator<Entry<String, Map<Object, Foo>>> mapIt
= map1.entrySet().iterator();
while (mapIt.hasNext()) {
final Entry<String, Map<Object, Foo>> mapEntry = mapIt.next();
mapIt.remove();
final Map<Object, int[]> submap = new HashMap<Object,int[]>();
map2.put(mapEntry.getKey(), submap);
final Iterator<Entry<Object,Foo>> fooIt
= mapEntry.getValue().entrySet().iterator();
while (fooIt.hasNext()) {
final Entry<Object,Foo> fooEntry = fooIt.next();
fooIt.remove();
submap.put(fooEntry.getKey(), fooEntry.getValue().toArray());
}
}
}
Run Code Online (Sandbox Code Playgroud)
我没有时间检查它,但我想这样的东西应该适用于scala Maps(假设你使用的scala 2.8终于来了):
mpO.mapValues(_.mapValues(_.toArray))
Run Code Online (Sandbox Code Playgroud)
它会占用你的外部地图,并用一个新地图"替换"所有内部地图,其中值是Int数组.键和地图的一般"结构"保持不变.根据scaladoc "生成的地图包裹原始地图而不复制任何元素.",因此它不会是真正的替代品.
如果你也做了
import scala.collection.JavaConversions._
Run Code Online (Sandbox Code Playgroud)
然后java映射可以像scala映射一样使用:JavaConversions包含一堆可以在scala和java集合之间转换的隐式方法.
BTW使用Map <String,HashMap <Object,Array <Int >>>最后可能不太方便,如果我是你,我会考虑引入一些隐藏这个结构复杂性的类.
编辑反映您的评论
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)))
}
}
Run Code Online (Sandbox Code Playgroud)
打印:
{a = {b = 1}}
地图(a - >地图(b - > 2))
显示implicits非常适用于外部和内部地图.这是JavaConversions对象的目的:即使您有一个java集合,您也可以将它用作类似的scala类(具有增强功能).
您不必执行任何其他操作,只需导入JavaConversions._
例如考虑字符串键;让我们调用输入数据:Map<String, Map<String, Object>> data
for (Entry<String, Map<String, Tuple>> entry : data.entrySet()) {
String itemKey = entry.getKey();
for (Entry<String, Object> innerEntry : entry.getValue().entrySet()) {
String innerKey = innerEntry.getKey();
Object o = innerEntry.getValue();
// whatever, here you have itemKey, innerKey and o
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13709 次 |
| 最近记录: |