Добавление нескольких значений (списка) с одним ключом на карту

У меня есть метод, который ищет мою БД и получает все значения из таблицы баров. Возьмите возвращенные строки и преобразуйте их в стержневые объекты и создайте складской объект из стержня. Бар является подклассом акций.

public Map<Stock, List<Bar>> findBars() throws Exception {
        BarConverter barConverter = new BarConverter();
        List<Bar> bars = new ArrayList<Bar>();
        Map<Stock, List<Bar>> map = new HashMap<Stock, List<Bar>>();

        // get rows from db
        List<Map<String, Object>> rows = dbClient.get(tableName, null, null, "id");
        for (Map<String, Object> row : rows) {
            // get bar object from row
            Bar bar = barConverter.setData(row, market);
            bars.add(bar);

            // set stock and map containing stock & bar
            Stock stock = new Stock(bar.getTicker(), market, bar.getExchange());
            map.put(stock, bars);
        }
        // return map
        return map;
    }

В настоящее время вышеуказанный метод дает вывод, например

{AAPL-US-NASDAQ=[AAPL,NASDAQ,2014-04-25,564.53,571.99,563.96,571.94,13000000,8.6174E8], GOOG-US-NASDAQ=[GOOG,NASDAQ,2014-04-25,1564.53,1581.99,263.96,371.94,13000000,1.6174E8], AAPL-US-NASDAQ=[AAPL,NASDAQ,2014-04-25,222.53,321.99,3121.96,571.94,13000000,8.6164E8] }

Как вы можете видеть в приведенном выше выводе, сначала это акции Apple со значениями столбцов, затем акции Google со значениями столбцов и снова акции Apple с некоторыми другими значениями столбцов. Как сгруппировать эти две панели Apple с помощью одной клавиши. то есть Map<Stock, List<Bar>>.

Ожидаемый результат

{AAPL-US-NASDAQ=[{AAPL,NASDAQ,2014-04-25,564.53,571.99,563.96,571.94,13000000,8.6174E8}, {AAPL,NASDAQ,2014-04-25,222.53,321.99,3121.96,571.94,13000000,8.6164E8}], GOOG-US-NASDAQ=[GOOG,NASDAQ,2014-04-25,1564.53,1581.99,263.96,371.94,13000000,1.6174E8]}

person user3580380    schedule 28.04.2014    source источник


Ответы (3)


Вы ищете мультикарту. В Java нет стандартной мультикарты.

Решение описано в руководстве по картам от Oracle и использует карту, чья значения - это списки.

Альтернативой является использование Multimap, предоставленного другим проектом. Apache Commons и Guava — это два популярных проекта, предоставляющих Multimaps.

person Zoyd    schedule 28.04.2014

Вероятно, вы можете использовать TreeMap, который является отсортированной картой. (отсортированные по естественному порядку элементов), он позволяет вам определить пользовательский порядок сортировки (через Comparable или Comparator). Ключ коллекции (объект Stock) также должен реализовывать сопоставимый интерфейс.

person maouven    schedule 28.04.2014

Техническое решение состоит в том, чтобы использовать какую-то «расширенную» карту, как описано в других ответах.

Я бы сказал, что когда вы получаете сложные карты для таких простых случаев, есть вероятность, что вы пытаетесь убежать от создания простого объекта. Это, вероятно, приведет вас к некоторым странным вещам, когда вам нужно агрегировать другую часть данных.

Создав новый класс, вы также сможете улучшить читабельность в дальнейшем, например, если вам нужно суммировать все Bar для заданного Stock :

/**
 * The simple way
 */
public class StockWithBarComposite {

   private Stock stock;

   private List<Bar> bars;

   /**
    * Some complex operation you can easily document here
    *
    * @return BigDecimal
    */
   public BigDecimal barSum() {
       // Loop, sum, whatever
   }

}
person Michael Técourt    schedule 28.04.2014