2016-07-07 5 views
1

Wie finden Sie die maximale LawInfo nach Datum für alle Spiele in der Gruppierung von LawInfoType?java 8 stream wie zu groupingBy im Ergebnis groupyBy?

Ich habe einfaches Modell:

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; 
} 

Hauptprüfung

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)); //!!!???? 

aber ich brauche durch Spiele in jeder Gruppe max nach Datum Gruppe erhalten

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

klein -> [ LawInfo (Fußball, max Datum), LawInfo (hockey, max Datum), LawInfo (Golf, max Datum), LawInfo (Basketball, max Datum)]

Mitte -> [LawInfo (Fußball, max Datum), LawInfo (hokey, max Datum), LawInfo (Golf, max Datum), LawInfo (Basketball, max Datum)]

groß -> [LawInfo (Fußball, maximales Datum), LawInfo (Golf, maximales Datum), LawInfo (Basketball, maximales Datum)]

Antwort

1

Sie könnten nach zwei Eigenschaften (getTextType und getGame) und einem max collector gruppieren .

Etwas wie folgt aus:

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

Danke! aber Karte >>! = Karte > – Atum

3

können Sie verwenden

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())); 
}); 

die

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 

mit Testdaten gedruckt werden. Beachten Sie, dass Datumswerte in diesem Bereich für Konsistenzprüfungen nicht ganz geeignet sind, da andere Daten dieses Datensatzes wie eine höhere Nummer in Ausdrucken aussehen können, da das Jahr nicht als signierte Zahl mit diesem Format gedruckt wird. Ich würde empfehlen, Daten mit vernünftigen Werten, z.B. mit vierstelligen positiven Zahl Jahren ...

+0

Vielen Dank! das ist gut! – Atum