1

我的申请与股票市场有关。我有一个持续更新名为 Price 的对象的提要。Price 有一个 HashMap,用于存储安全代码(String)和价格(Double)。每次出现新价格时,此对象都会更新。

该应用程序应该扫描价格的大动作。我有一个名为 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= {微软=17.64,苹果=93.85,谷歌=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);
    }
}

4

3 回答 3

6

您需要获取 HashMap 的副本,否则看起来您只是一遍又一遍地存储相同的 Map,这当然会被覆盖。使用这一行:

polledPrice.put(pollNumber, new HashMap(Price.getPricesMap()));

作为最简单的修复。

于 2009-02-23T08:42:01.463 回答
1

问题是Price.getPricesMap()每次都返回对同一个对象的引用。对我来说,这听起来像是一个糟糕的 API 设计——或者至少应该记录一个。

它可以通过在客户端代码中制作副本(如 Nick Fortescue 所建议的)或通过更改来修复Price。后者可以在每次发生实际更改时创建一个不可变映射,或者在每次调用时返回一个副本getPricesMap()

于 2009-02-23T09:34:22.803 回答
0

您真的需要每秒轮询您拥有的服务吗?这对我来说听起来有点像虐待。您应该在每次轮询之间至少等待 5-10 秒,尤其是在这涉及请求 Web 资源时。我认为尼克给了你一个足够好的答案,但过度投票是邪恶的!不要这样做。

于 2009-02-23T08:45:55.523 回答