2016-07-07 1 views
1

groupingBy LawInfoType의 모든 게임에 대해 날짜별로 최대 LawInfo를 찾는 방법은 무엇입니까?자바 8 스트림 그룹화 방법 결과 그룹화로?

내가 간단한 모델이 있습니다

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 (호키, 최대 날짜), LawInfo (골프, 최대 날짜), LawInfo (농구, 최대 날짜)]

중간 -> [LawInfo (축구, 최대 날짜), LawInfo (날조, 최대 날짜), LawInfo (골프, 최대 날짜), LawInfo (농구, 최대 날짜)]

큰 -> [LawInfo (축구, 최대 날짜), LawInfo (골프, 최대 날짜), LawInfo (농구, 최대 날짜)]

답변

1

두 개의 속성 (getTextType 및 getGame)으로 그룹화 할 수 있으며 max collector . 이 같은

뭔가 :

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

고마워요! 하지만지도 >>! > – 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 

를 인쇄 할 수 있습니다. 해당 데이터 세트의 다른 날짜가 일 경우이 연도가이 형식의 부호있는 숫자로 인쇄되지 않기 때문에 인쇄물에 더 높은 번호를 갖는 것처럼 보일 수 있으므로이 범위의 날짜 값은 일관성 검사에 적합하지 않습니다. 적절한 값으로 날짜를 생성하는 것이 좋습니다 (예 : 4 자리수의 양수기를 가지고 있습니다 ...

+0

감사합니다! 그 좋은! – Atum