2015-06-03 157 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