具有多个键的Java Map,以及作为值的计数

时间:2013-03-07 20:44:05

标签: java map hashmap key sales

我正在为小型企业创建一些图形软件。他们给了我去年的销售报告,在这份报告中,它显示了每个特定销售的“时间戳”和项目或“sku”,但没有特别的顺序。我想要弄清楚在特定日子销售的每件商品的数量。我知道我想使用map,但我不太熟悉在这种情况下如何使用它。如果sku在特定日期售出0件物品,我还需要地图返回0。这很难,因为我不知道报告中会有多少skus,报告也没有特别的顺序。

例如,报告可以显示:

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";

我想如何制作一张地图,我可以查看“2012-02-01”中售出多少“REN134”,希望获得4的回报。

我希望我足够清楚。 谢谢!

5 个答案:

答案 0 :(得分:3)

地图不能有重复的密钥。您需要做的是HashMap<String, ArrayList<String>>或类似的东西,其中键是SKU编号,值是所有日期的列表,然后您可以使用这些日期进行进一步排序和处理以计算事件的数量

答案 1 :(得分: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}

答案 2 :(得分:1)

考虑一下这段代码(我添加了你的样本数据)......它利用了Map不能有重复键的事实:

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.

注意:您需要解析输入文件(因为它可能是大数据)并使用显示的“地图计数器”技术。

答案 3 :(得分:0)

创建您自己的Item类,以封装skutimestamp字段。实施hashCodeequals方法,以便日后HashMap正常运行。

制作地图。

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

您需要使用值0初始化地图,以便稍后您可以获得哪些项目在一天内没有销售。

从报告中读取数据并创建Item个对象。如果它尚未存在于地图中,则将其存储在值为1的地图中。如果确实存在,则获取存储的值,添加1,然后存储新值。

答案 4 :(得分: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");