代码之家  ›  专栏  ›  技术社区  ›  dcp

Java中地图的浅拷贝

  •  99
  • dcp  · 技术社区  · 15 年前

    据我所知,有几种方法(也许还有其他方法)可以创建 Map 在Java中:

    Map<String, Object> data = new HashMap<String, Object>();
    Map<String, Object> shallowCopy;
    
    // first way
    shallowCopy = new HashMap<String, Object>(data);
    
    // second way
    shallowCopy = (Map<String, Object>) ((HashMap<String, Object>) data).clone();
    

    一种方式比另一种方式更可取吗?如果是,为什么?

    值得一提的是,第二种方式给出了一个“未经检查的演员阵容”警告。所以你必须加上 @SuppressWarnings("unchecked")

    @SuppressWarnings("unchecked")
    public Map<String, Object> getDataAsMap() {
        // return a shallow copy of the data map
        return (Map<String, Object>) ((HashMap<String, Object>) data).clone();
    }
    
    3 回复  |  直到 15 年前
        1
  •  106
  •   Community CDub    7 年前

    最好使用复制构造函数进行复制。 clone() 在Java中是不正确的(参见: How to properly override clone method?

    Josh Bloch on Design - Copy Constructor versus Cloning

    如果你读过我书中关于克隆的内容,特别是如果你读过字里行间的内容,你就会知道我认为 clone 被深深地打破了真遗憾 Cloneable 但它是坏的。

    Bloch(顺便说一句,他设计并实现了收集框架)甚至更进一步地说,他只提供 克隆() 方法只是“因为人们期待它”。他实际上根本不建议使用它。


    我认为更有趣的争论是复制构造函数是否比复制工厂好,但这是完全不同的讨论。

        2
  •  60
  •   nont    10 年前

    两个都不是:一个 constructor 您所指的是为 HashMap 实施 Map ,(也适用于其他),但不适用于地图界面本身(例如,考虑 Provider 映射接口的实现:您将找不到该构造函数)。

    clone() 方法,正如Josh Bloch所解释的。

    Map#putAll() :

    (可选操作)。此调用的效果与 对于从键k到键的每个映射,在此映射上调用put(k,v)一次 指定映射中的值v。

    例子:

    // HashMap here, but it works for every implementation of the Map interface
    Map<String, Object> data = new HashMap<String, Object>();
    Map<String, Object> shallowCopy = new HashMap<String, Object>();
    
    shallowCopy.putAll(data);
    
        3
  •  11
  •   Terris    10 年前

    在不知道其实现的情况下复制映射:

    static final Map shallowCopy(final Map source) throws Exception {
        final Map newMap = source.getClass().newInstance();
        newMap.putAll(source);
        return newMap;
    }