RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 860942
Accepted
Владислав
Владислав
Asked:2020-07-27 15:43:04 +0000 UTC2020-07-27 15:43:04 +0000 UTC 2020-07-27 15:43:04 +0000 UTC

为什么所有地图中的数据都会更新

  • 772

我不明白我的数据是如何在所有三个地图中更新的?

public void updateMap(Map<String, WagonFinalInfo> map, String wagons, String rates, String tariffs) {
    List<WagonRateAndTariff> listRateAndTariff = PrepareDateForInsert.fillListForUpdate(wagons, rates, tariffs);
    Map<String, WagonFinalInfo> oldMap = new HashMap<>(map);
    Map<String, WagonFinalInfo> tempNewMap = new HashMap<>(map);
    logger.debug("listRateAndTariff: {}", listRateAndTariff);
    for (Map.Entry<String, WagonFinalInfo> _map: tempNewMap.entrySet()) {
        for (WagonRateAndTariff list : listRateAndTariff) {
            if (_map.getKey().equals(list.getNumberOfWagon())) {
                if (_map.getValue().getRate() != (Double) list.getRate()) {
                    _map.getValue().setRate(list.getRate());
                }
                if (_map.getValue().getTariff() != (Double) list.getTariff()) {
                    _map.getValue().setTariff(list.getTariff());
                }
            }
        }
    }
    newMapWagonFinalInfo.putAll(tempNewMap);
    logger.info("newMapWagonFinalInfo: {}, oldMap: {}", newMapWagonFinalInfo, oldMap);
    classHandlerInsertRateOrTariff.insertDate(newMapWagonFinalInfo, oldMap);
    calculateYield(newMapWagonFinalInfo);
}

他们像 in 一样更新它tempNewMap,但是在输出中我得到了 inmap和 in 的更新oldMap,这不应该是。这是怎么发生的?

java
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Sergey Gornostaev
    2020-07-27T16:54:41Z2020-07-27T16:54:41Z

    因为集合存储对对象的引用,而不是对象本身。如果您正在创建两个视图

    Map<String, SomeClass> first = new HashMap<>();
    Map<String, SomeClass> second = new HashMap<>();
    

    将对象添加到第一个

    first.put('A', new SomeClass());
    

    然后“复制”到第二个

    second.put('A', first.get('A'));
    

    那么堆上只剩下一个对象,并且对该对象的引用被添加到第二个映射中。为避免这种情况,您需要执行深拷贝,即在堆上创建一个新对象并将数据从旧对象传输到该对象。将对象的复制功能留给自己是一个很好的做法。这通常通过声明一个复制构造函数来完成:

    class WagonFinalInfo {
        // Поля и другие конструкторы
        ...
    
        public WagonFinalInfo(WagonFinalInfo source) {
            setNumberOfWagons(source.getNumberOfWagons());
            // Копирование остальных данных
            ...
        }
    
        // Аксессоры и другие методы
        ...
    }
    

    然后在需要创建显示副本的代码位置

    Map<String, WagonFinalInfo> newMap =
        oldMap.entrySet()
              .stream()
              .collect(Collectors.toMap(Map.Entry::getKey, WagonFinalInfo::new));
    

    我怀疑在您的情况下,流不仅可用于创建深层副本,而且还可用于将使用二次算法的整个详细方法减少到几行,显着减少内存消耗和处理器周期。

    • 2
  2. Владислав
    2020-07-27T16:41:50Z2020-07-27T16:41:50Z

    不得不这样做

    for (Map.Entry<String, WagonFinalInfo> _map: oldMap.entrySet()) {
            String numberWagon = new String(_map.getKey());
            WagonFinalInfo wagonFinalInfo = new WagonFinalInfo(
                    _map.getValue().getNumberOfWagon(),
                    _map.getValue().getCountCircleDays(),
                    _map.getValue().getDistanceEmpty(),
                    _map.getValue().getCurrentNameOfStationOfWagon(),
                    _map.getValue().getCurrentKeyOfStationOfWagon(),
                    _map.getValue().getNameOfStationDepartureOfWagon(),
                    _map.getValue().getKeyOfStationDepartureOfWagon(),
                    _map.getValue().getRoute(),
                    _map.getValue().getCargo(),
                    _map.getValue().getCargoType());
            tempNewMap.put(numberWagon, wagonFinalInfo);
        }
    

    我从没想过我会遇到这种情况:)而且复制地图并不是那么容易的事实

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5