2013-03-07 2 views
1

Я работаю над созданием графического программного обеспечения для малого бизнеса. Они дали мне отчет о своих продажах в прошлом году, и в этом отчете он показывает «временную метку» и элемент или «ску» для каждой конкретной продажи, но в определенном порядке. Я полагаю, чтобы выяснить, сколько из каждого предмета продано в определенный день. Я знаю, что я предполагаю использовать карту, но я не слишком хорошо разбираюсь в том, как ее использовать в этом случае. Мне также нужно, чтобы карта возвращала 0, если для sku было продано 0 предметов в определенный день. Это сложно, потому что я не знаю, сколько будет skus в отчете, и отчет не имеет особого порядка.Карта Java с несколькими ключами и счет как значение

Например, отчет может показать:

sku="AKD123"; timestamp="2012-02-01"; 
sku="AKD123"; timestamp="2012-04-14"; 
sku="REN134"; timestamp="2012-02-01"; 
sku="PIK383"; timestamp="2012-10-07"; 
sku="REN134"; timestamp="2012-02-01"; 
sku="REN134"; timestamp="2012-02-01"; 
sku="PIK383"; timestamp="2012-03-01"; 
sku="REN134"; timestamp="2012-02-01"; 

Как я полагаю иметь карту, что я могу проверить, сколько «REN134» продаются на «2012-02-01», мы надеемся получить возврат 4.

Надеюсь, что я достаточно ясен. Спасибо!

+7

Рассматривали ли вы использование базы данных? Приклеивание этой информации в таблице приведет к тому, что подсчеты вы хотите получить. – David

+0

Взгляните на Коллекции Apache Commons [MultiValueMap] (http://commons.apache.org/proper/commons-collections//javadocs/api-release/org/apache/commons/collections/map/MultiValueMap.html) – Grim

ответ

3

Вам нужны две карты, один, чтобы соответствовать одному sku на некоторые даты и количество, и тот, который отображает каждую дату отсчету ... Попробуйте это ...

final static String skus[] = { 
    "AKD123", 
    "AKD123", 
    "REN134", 
    "PIK383", 
    "REN134", 
    "REN134", 
    "PIK383", 
    "REN134" 
}; 

final static String timestamp[] = { 
    "2012-02-01", 
    "2012-04-14", 
    "2012-02-01", 
    "2012-10-07", 
    "2012-02-01", 
    "2012-02-01", 
    "2012-03-01", 
    "2012-02-01" 
}; 


@Test 
public void countSkusPerDay() { 
    Map<String, Map<String, Integer>> countMap = new HashMap<>(); 
    for(int i = 0; i < skus.length; i++) { 
     String sku = skus[i]; 
     String date = timestamp[i]; 
     Map<String, Integer> countPerDateMap = countMap.get(sku); 
     if(countPerDateMap == null) { 
      countPerDateMap = new HashMap<>(); 
      countMap.put(sku, countPerDateMap); 
     } 
     Integer count = countPerDateMap.get(date); 
     if(count == null) { 
      countPerDateMap.put(date, 1); 
     } else { 
      countPerDateMap.put(date, count.intValue() + 1); 
     } 
    } 

    for(Map.Entry<String, Map<String, Integer>> e : countMap.entrySet()) { 
     System.out.println("sku " + e.getKey() + " sold in " + e.getValue().size() + " day(s) " + e.getValue()); 
    } 
} 

Выход

sku REN134 sold in 1 day(s) {2012-02-01=4} 
sku PIK383 sold in 2 day(s) {2012-10-07=1, 2012-03-01=1} 
sku AKD123 sold in 2 day(s) {2012-02-01=1, 2012-04-14=1} 
+0

приятный ответ снова :) .. –

3

Карта не может иметь дубликаты ключей. Вам нужно будет сделать HashMap<String, ArrayList<String>> или что-то в этом роде, где ключ - это номер SKU, а значение - это список всех дат, которые вы затем можете использовать для дальнейшей сортировки и обработки, чтобы подсчитывать вхождения.

+0

Возможно, также может быть полезной карта > - внутренняя карта - это карта с даты для подсчета. –

+0

Конечно, вы всегда можете хранить более ассоциативную информацию, перейдя «глубже» с вложенными Картами. Хорошее предложение, в зависимости от того, насколько сложный OP хочет получить и является ли удобочитаемость проблемой (я лично нахожу много вложенных карт немного запутывающим, но это только я). – asteri

0

Создайте свой собственный класс Item для инкапсуляции полей sku и timestamp. Внедрите методы hashCode и equals, а затем HashMap будет работать правильно.

Создайте свою карту.

Map<Item, Integer> salesMap = new HashMap<Item, Integer>(); 

Вам необходимо инициализировать карту со значениями 0, так что позже вы можете получить, какие элементы не имеют продажи в день.

Прочтите данные из отчета и создайте свои объекты Item. Если он еще не существует на карте, сохраните его на карте со значением 1. Если он существует, возьмите сохраненное значение, добавьте 1 и сохраните новое значение.

1

Рассмотрим этот код (я добавил свои выборочные данные) ... его, воспользовавшись тем, что на карте не может иметь дубликаты ключей:

import java.util.HashMap; 
import java.util.Map; 
import java.util.Set; 

public class TEST 
{ 
    public static void main(String[] args) 
    { 
/* 
sku="AKD123"; timestamp="2012-02-01"; 
sku="AKD123"; timestamp="2012-04-14"; 
sku="REN134"; timestamp="2012-02-01"; 
sku="PIK383"; timestamp="2012-10-07"; 
sku="REN134"; timestamp="2012-02-01"; 
sku="REN134"; timestamp="2012-02-01"; 
sku="PIK383"; timestamp="2012-03-01"; 
sku="REN134"; timestamp="2012-02-01"; 

    Transform into this array: 
*/ 
    String[] inputValues = new String[] 
    { "AKD123|2012-02-01", "AKD123|2012-04-14", "REN134|2012-02-01", "PIK383|2012-10-07", "REN134|2012-02-01", "REN134|2012-02-01", 
     "PIK383|2012-03-01", "REN134|2012-02-01" }; 

    // That is your map 
    Map<String, Integer> mapCouter = new HashMap<String, Integer>(); 
    // now iterate though all SKU sales 
    for (String key : inputValues) 
    { 
     Integer count = mapCouter.get(key); 
     if (count == null) 
     { 
     // not found... lets init. 
     count = 0; // using java autoboxing. 
     } 
     mapCouter.put(key, ++count); // incrementing by 1 before storing in the Map 
    } 
    System.out.println("Report:"); 
    Set<String> keys = mapCouter.keySet(); 
    for (String key : keys) 
    { 
     System.out.println("key: " + key + " has " + mapCouter.get(key) + " occurences."); 
    } 
    } 
} 

Он производит следующий вывод:

Report: 
key: REN134|2012-02-01 has 4 occurences. 
key: AKD123|2012-04-14 has 1 occurences. 
key: PIK383|2012-10-07 has 1 occurences. 
key: AKD123|2012-02-01 has 1 occurences. 
key: PIK383|2012-03-01 has 1 occurences. 

ПРИМЕЧАНИЕ: Вам нужно будет разобрать через входной файл (так как это может быть большой данные) и использовать эту технику «Карта счетчика», как показано.

0

А как насчет карты Guava Multisets, как Map<String,Multiset<String>> itemToDatesSoldMap = new HashMap<>();.Это позволило бы нам сделать что-то вроде

public int countSalesOfItemOnDate(String sku, String timestamp){ 
    Multiset<String> timestampMultiset = itemToDatesSoldMap.get(sku); 
    if(timestampMultiset == null){ 
     return 0; 
    } 
    return timestampMultiset.count(timestamp); 
} 

countSalesOfItemOnDate("REN134","2012-02-01");