我的申请与股票市场有关。我有一个不断更新名为Price的对象的Feed。 Price有一个存储安全代码(String)和价格(Double)的HashMap。每当新价格出现时,此对象都会更新。
该应用程序应该扫描大幅移动的价格。我有一个名为Poller的独立类,它每秒轮询Price对象并拍摄价格的快照。快照是如上所述的HashMap。然后我想将这个HashMap的价格与pollNumber一起存储在另一个HashMap中我以后可以传递pollNumber并在与该pollNumber对应的时间输出价格。
但相反,我得到所有以前的价格被覆盖并输出类似于下面的价格。
0:{MSFT = 17.67,AAPL = 93.85,GOOG = 333.86} {0 = {MSFT = 17.67,AAPL = 93.85,GOOG = 333.86}}
1:{MSFT = 17.64,AAPL = 93.85,GOOG = 334.02} {0 = {MSFT = 17.64,AAPL = 93.85,GOOG = 334.02},1 = {MSFT = 17.64,AAPL = 93.85,GOOG = 334.02}}
2:{MSFT = 17.64,AAPL = 93.85,GOOG = 334.08} {0 = {MSFT = 17.64,AAPL = 93.85,GOOG = 334.08},1 = {MSFT = 17.64,AAPL = 93.85,GOOG = 334.08}, 2 = {MSFT = 17.64,AAPL = 93.85,GOOG = 334.08}}
3:{MSFT = 17.65,AAPL = 93.83,GOOG = 334.08} {0 = {MSFT = 17.65,AAPL = 93.83,GOOG = 334.08},1 = {MSFT = 17.65,AAPL = 93.83,GOOG = 334.08},2 = {MSFT = 17.65,AAPL = 93.83,GOOG = 334.08},3 = {MSFT = 17.65,AAPL = 93.83,GOOG = 334.08}}
4:{MSFT = 17.64,AAPL = 93.83,GOOG = 334.07} {0 = {MSFT = 17.64,AAPL = 93.83,GOOG = 334.07},1 = {MSFT = 17.64,AAPL = 93.83,GOOG = 334.07},2 = {MSFT = 17.64,AAPL = 93.83,GOOG = 334.07},3 = {MSFT = 17.64,AAPL = 93.83,GOOG = 334.07},4 = {MSFT = 17.64,AAPL = 93.83,GOOG = 334.07}}
正如您所看到的那样,当我打印出应该具有不同价格序列的整个HashMap时,它们都是相同的。
基本上.put()函数会以某种方式覆盖旧条目。
如果你知道如何修复这种行为,那么HashMap(大的)每次都有一个新的价格序列条目。
public class Poller {
private final int period=1000;
private final int delay=1000;
private static int pollNumber=0;
private static HashMap<Integer,HashMap<String,Double>>
polledPrice = new HashMap<Integer, HashMap<String,Double>>();
public void pollPrice(){
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
// System.out.println(Price.getPricesMap());
System.out.println(pollNumber+" : "+Price.getPricesMap());
polledPrice.put(pollNumber, Price.getPricesMap());
System.out.println(polledPrice);
pollNumber = pollNumber+1;
Time atime = new Time();
atime.addToTimeMap(pollNumber);
}
}, delay, period);
}
}
答案 0 :(得分:6)
你需要复制HashMap,否则看起来你只是一遍又一遍地存储相同的Map,这当然会被覆盖。使用此行:
polledPrice.put(pollNumber, new HashMap(Price.getPricesMap()));
最简单的解决方法。
答案 1 :(得分:1)
问题是Price.getPricesMap()
每次都返回对同一对象的引用。这对我来说听起来像是一个糟糕的API设计 - 或者至少有一个应该被记录下来。
可以通过在客户端代码(as suggested by Nick Fortescue)中进行复制或更改Price
来解决此问题。后者可以在每次实际更改时创建不可变映射,也可以在每次调用时将副本返回getPricesMap()
。
答案 2 :(得分:0)
你真的需要每秒查看你所拥有的服务吗?这听起来有点像虐待我。您应该至少在每次轮询之间等待5-10秒,特别是如果这涉及请求Web资源。我认为尼克给了你足够好的答案,但过度的民意调查是邪恶的!不要这样做。