2015-06-03 83 views
1

给出一个Java类Somethingjava8流分组汇总

class Something { 
    String parent; 
    String parentName; 
    String child; 
    Date at; 
    int noThings; 

    Something(String parent, String parentName, String child, Date at, int noThings) { 
      this.parent = parent; 
      this.parentName = parentName; 
      this.child = child; 
      this.at = at; 
      this.noThings = noThings; 
     } 

     String getParent() { return parent; } 
     String getChild() { return child; } 
     int getNoThings() { return noThings; } 
} 

我有一些对象的列表,

List<Something> hrlySomethings = Arrays.asList(
    new Something("parent1", "pname1", "child1", new Date("01-May-2015 10:00:00"), 4), 
    new Something("parent1", "pname1", "child1", new Date("01-May-2015 12:00:00"), 2), 
    new Something("parent1", "pname1", "child1", new Date("01-May-2015 17:00:00"), 8), 
    new Something("parent1", "pname1", "child2", new Date("01-May-2015 07:00:00"), 12), 
    new Something("parent1", "pname1", "child2", new Date("01-May-2015 17:00:00"), 14), 
    new Something("parent2", "pname2", "child3", new Date("01-May-2015 11:00:00"), 3), 
    new Something("parent2", "pname2", "child3", new Date("01-May-2015 16:00:00"), 2)); 

我想组由父母和孩子,然后将对象找到总/在过去的24小时内,“noThings”字段的总和。

List<Something> dailySomethings = Arrays.asList(
    new Something("parent1", "pname1", "child1", new Date("01-May-2015 00:00:00"), 14), 
    new Something("parent1", "pname1", "child2", new Date("01-May-2015 00:00:00"), 26), 
    new Something("parent2", "pname2", "child3", new Date("01-May-2015 00:00:00"), 5)) 

我试图使用流要做到这一点

我能弄清楚如何使用分组来获得地图的地图,总

Map<String,Map<String,IntSummaryStatistics>> daily = 
     hrlySomethings.stream().collect(
    Collectors.groupingBy(Something ::getParent, 
    Collectors.groupingBy(ClientCollectionsReceived::getChild, 
    Collectors.summarizingInt(ClientCollectionsReceived::getNoThings)))); 

我可以弄清楚如何让基于家长和孩子一个独特的名单,

Date startHour = "01-May-2015 00:00:00"; 
    int totalNoThings = 0; // don't know how to put sum in here 
    List<Something> newList 
     = hrlySomethings.stream() 
      .map((Something other) -> { 
        return new Something(other.getParent(), 
        other.getChild(), startHour, totalNoThings); 
       }) 
      .distinct() 
      .collect(Collectors.toList()); 

但我不知道如何将两者结合起来,以获取与总数不同的清单。这可能吗?

回答

2

首先,我假定您正在使用java.util.Date(尽管我建议您移至新的java.time API)。其次,我认为Something班也正确实施了equalshashCode。此外,更干将是必要的:

String getParentName() { return parentName; } 
Date getAt() { return at; } 

根据这些假设你的任务就可以解决这样的:

List<Something> dailySomethings = hrlySomethings.stream().collect(
    Collectors.groupingBy(
     smth -> new Something(smth.getParent(), 
           smth.getParentName(), 
           smth.getChild(), 
           new Date(smth.getAt().getYear(), 
             smth.getAt().getMonth(), 
             smth.getAt().getDate()), 
           0), 
     Collectors.summingInt(Something::getNoThings) 
    )).entrySet().stream() 
       .map(entry -> new Something(entry.getKey().getParent(), 
              entry.getKey().getParentName(), 
              entry.getKey().getChild(), 
              entry.getKey().getAt(), 
              entry.getValue())) 
       .collect(Collectors.toList()); 

我们使用groupingBy只有一次,但创建一个合适的分组关键,这是SomethingparentparentNamechild设为原始,at改为当天开始,noThings设为零。这样你就可以分组你想要的东西。如果您只需要总和,那么summarizingInt是不必要的,summingInt就足够了。之后,我们将生成的地图转换为列表,创建新的Something对象,其中noThings从地图值中填充,其余部分从键填充。

+0

工作!非常感谢您的意见。 – IncompleteCoder