HashMap переписывается каждый раз, когда я использую .put () - PullRequest
1 голос
/ 23 февраля 2009

Моя заявка связана с фондовым рынком. У меня есть канал, который постоянно обновляет объект с именем Цена. Цена имеет 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 = {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);
    }
}

Ответы [ 3 ]

6 голосов
/ 23 февраля 2009

Вам нужно взять копию HashMap, иначе похоже, что вы просто сохраняете одну и ту же Карту снова и снова, что, конечно, перезаписывается. Используйте эту строку:

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

Как самое простое исправление.

1 голос
/ 23 февраля 2009

Проблема в том, что Price.getPricesMap() каждый раз возвращает ссылку на один и тот же объект. Для меня это звучит как плохой дизайн API - или, по крайней мере, тот, который должен быть задокументирован.

Это можно исправить либо сделав копию в коде клиента (, как предложил Ник Фортескью ), либо изменив Price. Последний может либо создавать неизменяемую карту каждый раз, когда происходит реальное изменение, либо возвращать копию при каждом вызове getPricesMap().

0 голосов
/ 23 февраля 2009

Тебе действительно нужно опросить, какой сервис ты имеешь каждую секунду? Это звучит как оскорбление для меня. Вам следует подождать не менее 5-10 секунд между каждым опросом, особенно если это связано с запросом веб-ресурса. Я думаю, что Ник дал вам достаточно хороший ответ, но чрезмерный опрос - это зло! Не делай этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...