快速复制哈希表

3

可能重复:
Java中HashMap的克隆工具

我有一个一对一的映射,如下所示:

      HashMap<Integer, ArrayList<Double>> matrix;

整数是索引,ArrayList 的维度约为 50。索引的大小可能高达一百万。我希望尽快制作一个副本(包括 ArrayList 值)。

我按照以下方式操作:

 public Map<Integer,ArrayList<Double>> getCloneOfMatrix(){
 Map<Integer, ArrayList<Double>> newMatrix = new HashMap<Integer,ArrayList<Double>>(); 
    for(int i=0 ; i < indexSize; i++){
        ArrayList<Double> arrList = new ArrayList<Double>();
        arrList=(ArrayList<Double>) matrix.get(i).clone();
        newMatrix.put(i,arrList);

    }           
    return   newMatrix;
}

我发现这个计算成本很高,有没有更快的方法来做它。

可能只有几个百分点,但是在给arrList分配另一个引用之前立即将其分配为new ArrayList<Double>();是完全没有意义的。 - Pete Kirkham
3
有一张地图像列表一样起作用,这很奇怪……因为你正在使用 for [0..indexSize] 迭代地图,你为什么不使用列表呢?但是请注意不要改变原句意思。 - Francisco Spaeth
我不明白你的意思。能否请您详细说明一下? - thetna
2
有一些针对稀疏矩阵的内置库(例如Colt),我相信使用这些库可以节省您的实现时间。 - amit
对于像那样的巨大Map进行深度复制始终是计算上昂贵的。如果您期望处理如此大量的数据,我不确定Map是否是正确的选择。 - Vala
尝试一下这个问题的答案:hashmap的克隆实用程序 - Adam Arold
5个回答

4

最快的方法是避免一开始就需要复制。

如果使用写时复制(Copy-On-Write)方法,您可以拥有两个对同一结构的引用,但是两者都不会看到其他人所做的更改。这避免了复制所有内容的需要,并且根据您的使用情况,也避免了复制任何内容的需要。


1
这是一个有见地的回答,但如果能解释如何实现写时复制会更有帮助。 - L. Blanc

3
您在每次迭代中使用了 Map.get(),它会依次调用 hashCode() 函数,这可能是微不足道的,也可能不是,然后在映射数据库中进行搜索。
您可以简单地遍历 Map 中保存的 Entry 集合,这将大大减少总共消耗的时间(鉴于 ArrayList 相对较小)。
for(Entry<Integer,ArrayList<Double> entry : matrix.entrySet()) {
        //get the key using entry.getKey()
        //get the value (the ArrayList) using entry.getValue()
}     

同时 - 你可能想要考虑使用处理数学矩阵的库。例如,Colt 提供了密集矩阵和稀疏矩阵的实现,而且已经为你实现并测试。


Integer.hashCode是微不足道的,但你仍然可以直接迭代来节省一点。 - Pete Kirkham
@PeteKirkham:hashCode()的注释更多是一般情况,在这里确实很琐碎,但映射查找不是。 - amit

0

0

虽然这不会在复杂度方面有所帮助,但在Java中使用ArrayList<Double>需要对每个元素进行装箱,而使用double[]代替会使每个单位的成本更低,因为它似乎是一个稀疏矩阵,所以第二维是固定的。

除此之外,使用经典的稀疏矩阵表示之一(假设它是稀疏的,否则你就不会费心用哈希映射)。


0

正如this问题的答案所述,您应该尝试使用序列化/反序列化进行克隆。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接