将地图复制到另一个新地图

问题描述 投票:2回答:7

我有2个HashMap如下:

@Session
private Map< Integer, List< ObjectA >> keyMap;

@Session
private Map< Integer, List< ObjectA >> keyMap2;

首先,我将在keyMap中放入一些数据,然后我尝试将数据存储在keyMapkeyMap2

keyMap2 = keyMap;

然后,我将在keyMap中编辑一些数据。但是,keyMap2中的值会随着我在keyMap编辑的内容而改变。

据我所知,这是因为keyMap2只指向keyMap指针,所以keyMap的任何变化,它都会反映在keyMap2,因为同样的指针。 (如果我错了,请纠正我。)

我希望保持keyMap2值没有像keyMap这样的变化。任何想法,除了我循环keyMap并在keyMap2内逐个放1。

java pointers hashmap
7个回答
1
投票

您可以像这样使用Java 8 Stream进行复制。

    Map<String, List<ObjectA>> keyMap2 = keyMap.entrySet().stream()
        .map(e -> new AbstractMap.SimpleEntry<>(e.getKey(), new ArrayList<>(e.getValue())))
        .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));

此代码复制keyMap值的列表。


0
投票

正如你正确提到的那样,keyMap2指向与keyMap相同的HashMap

但如果你这样做:

keyMap2 = (HashMap<String, String>) keyMap.clone();

这将使keyMap和点keyMap2复制到该副本。对keyMap的任何更改都不会反映在副本中

这将解决您的问题


0
投票

在Java中没有像指针这样的东西。使用(使用C \ C ++),因此您的更改不会反映出来。您可以使用:

keyMap2 = (HashMap<String, String>) keyMap.clone();

要么:

keyMap.putAll(keyMap2) //This will add all the keys in "keymap" to "keymap2"
//Source: http://docs.oracle.com/javase/7/docs/api/java/util/Map.html

同样,这些变化不会反映,因为Java中没有pointers

干杯。


0
投票

编辑:正如评论中所提到的,由于通过引用复制包含的List,原始方法将不起作用。

如果使用Java8流的方法不起作用,则另一种可能性是迭代Map:

for (keyMap.Entry<Integer, List<ObjectA>> entry : map.entrySet()) {
    //Code
}

然后,您可以使用entry.getKey()将内容复制到keyMap2中,并从entry.getValue()将列表的浅或深副本复制到keyMap2中

如果浅层副本(通过引用复制ObjectA)只需要new ArrayList<ObjectA>(entry.getValue())sh工作,但对于深层复制(需要ObjectA的新实例),需要有关该对象的更多信息。


原版的:

您需要完整地复制hashmap。

这包括在:copying a java hashmap

本质上private Map< Integer, List< ObjectA >> keyMap2 = new HashMap< Integer, List< ObjectA >>(keyMap);

或者keyMap2.addAll(keyMap);


0
投票

您遇到的问题称为别名。

为了打破你的情况,你必须:

  • 在你的班级clone上定义ObjectA方法
  • 迭代第一张地图的keySet,因此: 获取与特定键关联的List实例 创建该列表的新实例 迭代前者,克隆包含的元素并将它们放在后者中 将新列表放在第二个映射中,以及用于获取原始列表的键

这样,您从头开始创建一个新列表和一组完整的元素,这些元素在内容方面与原始元素相同,但在内存中不是相同的对象。


0
投票

使用Java 8 Stream和方法参考:

 Map<Integer, List<ObjectA>> keyMap2 = keyMap.entrySet().stream()
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

或者,如果您想将keyMap中的List复制到另一个列表中

Map<Integer, List<ObjectA>> keyMap2 = keyMap.entrySet().stream()
                    .collect(Collectors.toMap(Map.Entry::getKey, e -> new ArrayList<ObjectA>(e.getValue())));

0
投票
keyMap2 = new HashMap<Integer, List<ObjectA>>(keyMap);

将HashMap换成您喜欢或需要的任何Map实现。

© www.soinside.com 2019 - 2024. All rights reserved.