简体   繁体   English

从列表派生密钥时如何迭代guava MultiMap

[英]How to iterate guava MultiMap when the key is derived from a List

I have a List of Orders with Order Date and Order Value. 我有一个带有订单日期和订单价值的订单清单。 How do I group by order date and calculate the total Order Value per Order Date. 如何按订单日期分组并计算每个订单日期的总订单价值。 How can I achieve this in Google Guava? 如何在Google Guava中实现这一目标? If its complicating things.. how do I achieve this in Java collections? 如果它使事情复杂化,那么如何在Java集合中实现呢?

Order POJO 订购POJO

Date date;
Integer Value;

Util.java Util.java

    ListMultimap<Date, Integer> listMultiMap = ArrayListMultimap.create();
    for(Order o : orders){
      listMultiMap.put(o.date, o.value);
   }
   //Now how do I iterate this listMultiMap and calculate the total value?

I don't think Guava is necessarily the best tool here...nor any normal map, for that matter: if you will have a huge amount of Orders, you should think about using Java8 Streams, that will let you parallelise your calculation. 对于那件事,我认为Guava不一定不是最好的工具……也不是任何普通地图:如果您有大量的Orders,则应考虑使用Java8 Streams,它将使您并行化计算。 It will also have optimization about primitive types (int vs. Integer)... 它还将对原始类型(int与Integer)进行优化。

In any case, for the specific use case you describe and following the starting code you posted, here it is a potential solution (using LocalDate instead of Date just because it's more handy): 无论如何,对于您描述的特定用例并按照发布的起始代码进行操作,这是一种潜在的解决方案(使用LocalDate代替Date只是因为它更方便):

@Test
public void test(){

    // Basic test data
    Order today1 = new Order(LocalDate.now(),1);
    Order today2 = new Order(LocalDate.now(),2);
    Order today3 = new Order(LocalDate.now(),5);
    Order tomorrow1 = new Order(LocalDate.now().plusDays(1),2);
    Order yesterday1 = new Order(LocalDate.now().minusDays(1),5);
    Order yesterday2 = new Order(LocalDate.now().minusDays(1),4);
    List<Order> list = Lists.newArrayList(today1,today2,today3,tomorrow1,yesterday1,yesterday2);

    // Setup multimap and fill it with Orders
    ListMultimap<LocalDate, Integer> mm = ArrayListMultimap.create();
    for(Order o : list){
        mm.put(o.date,o.value);
    }

    // At this point, all you need to do is, for each date "bucket", sum up all values.
    Map<LocalDate, Integer> resultMap = Maps.newHashMap();
    for(LocalDate d : mm.keySet()){
        List<Integer> values = mm.get(d);
        int valuesSum = 0;
        for(int i : values){
            valuesSum += i;
        }
        resultMap.put(d,valuesSum);
    }

    /*
    * Result map should contain:
    * today -> 8
    * tomorrow -> 2
    * yesterday -> 9
    * */
    assertThat(resultMap.size(), is(3));
    assertThat(resultMap.get(LocalDate.now()), is(8));
    assertThat(resultMap.get(LocalDate.now().minusDays(1)), is(9));
    assertThat(resultMap.get(LocalDate.now().plusDays(1)), is(2));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM