2013-03-07 74 views
1

我正在为小型企业创建一些图形软件。他们去年向我汇报了他们的销售情况,并在这份报告中显示了每个特定销售的“时间戳”和项目或“sku”,但没有特定的顺序。我想知道在特定的日子里每件物品有多少。我知道我想使用地图,但我不太熟悉在这种情况下如何使用它。我还需要地图返回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 2013-03-07 20:46:38

+0

查看Apache Commons Collections [MultiValueMap](http://commons.apache.org/proper/commons-collections//javadocs/api-release/org/apache/commons/collections/map/MultiValueMap.html) – Grim 2013-03-07 20:52:58

回答

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

好的答案再次:) – 2013-03-08 18:50:38

3

地图不能有重复的键。你需要做的是有一个HashMap<String, ArrayList<String>>或类似的东西,其中关键是SKU编号,值是一个所有日期列表,然后你可以使用它进一步分类和处理来计算出现次数。

+0

也许地图<字符串,地图<日期,整数>>也可能有用 - 内部地图是从日期到数量的地图。 – 2013-03-07 20:48:39

+0

当然,您可以通过嵌套地图进行“更深入”来始终存储更多关联信息。很好的建议,取决于OP想要得到多少复杂以及是否需要考虑可读性(我个人发现很多嵌套地图有点混淆,但这只是我)。 – asteri 2013-03-07 20:49:40

0

创建您自己的Item类来封装skutimestamp字段。实施hashCodeequals方法,以便HashMap可以正常工作。

创建您的地图。

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

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

从报告中读取数据并创建您的Item对象。如果地图中尚不存在,则将其存储在地图中,值为1.如果它存在,则取存储的值,加1,并存储新值。

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. 

注:您将需要通过输入文件来分析(因为它可能是大数据),并使用此显示“地图计数器”技术。

0

什么有地图的Guava MultisetsMap<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"); 
相关问题