2016-07-07 75 views
1

如何根據日期查找最大LawInfo所有遊戲在groupingBy LawInfoType?java 8流如何在結果groupingBy中分組?

我有簡單的模型:

public enum Game { 
    football, 
    hokey, 
    golf, 
    basketball 
} 

public class LawInfo { 
    private Date minDate; 
    private State state; 
    private LawInfoType textType; 
    private String lawInfoText; 
    private Game game; 
} 

public enum LawInfoType { 
    big, middle , small; 
} 

public enum State { 
    draft, ready, cancel; 
} 

主要測試

List<LawInfo> list = new ArrayList<>(); 

     LawInfo info = null; 
     Random random = new Random(123); 
     for (int i = 0; i < 3; i++) { 

      for (State state : State.values()) { 
       for (LawInfoType lawInfoType : LawInfoType.values()) { 
        for (Game game : Game.values()) { 
         info = new LawInfo(new Date(random.nextLong()), state, lawInfoType, "TEXT", game); 
         list.add(info); 
        } 

       } 
      } 
     } 

     Predicate<LawInfo> isReady = l->l.getState().equals(State.ready); 


    Map<LawInfoType, List<LawInfo>> map0 = list.stream() 
       .filter(isReady) 
       .collect(groupingBy(LawInfo::getTextType)); //!!!???? 

但我需要按日期按遊戲

like this : Map<LawInfoType, List<LawInfo>> 

小,每組最多獲得 - > [ LawInfo(足球,最大日期),LawInfo(hokey,最大日期),LawInfo(高爾夫,最大日期),LawInfo(籃球,最大日期)]

中間 - > [LawInfo(足球,最大日),LawInfo(虛情假意,最大日),LawInfo(高爾夫,最大日),LawInfo(籃球,最大日)

大 - > [LawInfo(足球,最大日期),LawInfo(hokey,最大日期),LawInfo(高爾夫,最大日期),LawInfo(籃球,最大日期)]

回答

1

您可以通過兩個屬性(getTextType和getGame) 。

事情是這樣的:

Map<LawInfoType, Map<Game, Optional<LawInfo>>> map0 = list.stream().collect(
    Collectors.groupingBy(LawInfo::getTextType, 
     Collectors.groupingBy(LawInfo::getGame,   
       Collectors.maxBy(Comparator.comparing(LawInfo::getMinDate)) 
    ))); 
+1

謝謝!但是Map >>!= Map > – Atum

3

您可以使用

Map<LawInfoType, List<LawInfo>> result = list.stream() 
    .filter(l -> l.getState()==State.ready) 
    .collect(
     Collectors.groupingBy(LawInfo::getTextType, 
      Collectors.collectingAndThen(
       Collectors.groupingBy(LawInfo::getGame, 
        Collectors.maxBy(Comparator.comparing(LawInfo::getMinDate))), 
       m -> m.values().stream().map(Optional::get).collect(Collectors.toList()) 
     ))); 

result.forEach((k,v) -> { 
    System.out.println(k); 
    v.forEach(l -> System.out.printf("%14s, %15tF%n", l.getGame(), l.getMinDate())); 
}); 

,它將打印

big 
      golf, 250345012-06-20 
    basketball, 53051589-05-19 
     football, 177220545-11-30 
     hokey, 277009605-05-01 
middle 
      golf, 24379695-11-03 
    basketball, 283700233-08-25 
     football, 248125707-04-08 
     hokey, 195919793-04-22 
small 
      golf, 152237339-07-10 
    basketball, 269880024-08-24 
     football, 285393288-11-14 
     hokey, 276036745-09-23 

與您的測試數據。請注意,該範圍內的日期值不太適合一致性檢查,因爲此數據集的其他日期可能會看起來,因爲年份不打印爲具有此格式的帶符號數字。我建議生成具有合理值的日期,例如有四位正數年...

+0

謝謝!這很好! – Atum