2017-08-15 31 views
0

我无法找到这个问题的确切答案,所以我只想问自己。Java:使用另一个Map的信息创建一个新地图,而不是创建一个参考

我有一个Map<Integer, State> states;有关特定日期的信息。每天当天的信息保存在Map<Integer, DayLog> dayLog;中,其中DayLog包含保存的Map<Integer, State> states;

的问题是,当我改变了实时states,都在dayLog保存修改states过,由于创建的参考,而不是新创建的信息。

如何将信息保存在新的地图中而不是仅创建参考?

希望这是可以理解的。 在此先感谢! :)

+2

请显示相关代码段而不是描述它们 –

回答

3

您需要在您创建DayLog做一次深层副本:

/** 
* Create a new DayLog object with the current set of states. 
* This constructor will make a deep copy of the states so they cannot be 
* changed later outside of this log. 
* @param currentStates the states as they exist right now 
*/ 
public DayLog(Map<Integer, State> currentStates) { 
    this.states = new HashMap<>(); 
    for(Integer key : currentStates.keySet()) { 
     State state = currentStates.get(key); 
     State newState = new State(state); // assuming copy constructor 
     this.states.put(key, newState); 
    } 
} 

可能有多种方式来实现这一点(克隆,具有state.archive()方法,或某事),但这将是基本的方法论 - 创建一个现在存在的州的地图,不要参考实时数据。

或者,使用数据库 - 它非常擅长,存储数据。

+0

您可能会更加简洁地使用lambda表达式。 – duffymo

+0

也许吧。自从lambdas成为一件大事之前,就没有专业地完成Java。但是如果有人知道如何去做,他们会看看它做了什么,然后去“哦,是的,复制构造函数,这就是我需要的!”并将其放入他们使用的任何解决方案中。 – corsiKa

+0

@duffymo我也可以通过不隐藏this.states来做更好的事情 - 它只会导致bug在我那里做。 – corsiKa

0

如何将信息保存在新地图中而不是仅创建 参考?

您可以创建HashMap与采用作为参数的构造函数Map

public HashMap(Map<? extends K, ? extends V> m) 

从的Javadoc:

构造具有相同的映射关系与指定Map一个新的HashMap 。

它会将所有元素放在新的HashMap中。

然后清除初始Mapmap.clear()

然后,当您在初始地图中添加元素时,它不会对刚创建的Map产生副作用。

+0

虽然这不会解决问题。 '国家=新国家(5); Map map = new HashMap <>(); map.put(1,S); Map newMap = new HashMap(map); s.setState(6);的System.out.println(newMap.get(1).getState()); //打印6,而不是5' – corsiKa

+0

如果在实例化之后清除初始映射,它将会。 – davidxxx

+0

等一下,什么?不,它不会。问题在于,在地图之外有人正在改变这些值。如果你想阻止他们改变它们,你必须打破新地图对这些值的访问!向我展示一个能够说明你的观点的MCVE。 – corsiKa

相关问题