Reputation: 1301
how to find max LawInfo by date fo all games in groupingBy LawInfoType?
i have simple model :
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;
}
main test
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)); //!!!????
but I need to get in each group max by date group by games
like this : Map<LawInfoType, List<LawInfo>>
small->[LawInfo(football, max date),LawInfo(hokey, max date) ,LawInfo(golf, max date) , LawInfo(basketball, max date)]
middle->[LawInfo(football, max date),LawInfo(hokey, max date) ,LawInfo(golf, max date) , LawInfo(basketball, max date)]
big->[LawInfo(football, max date),LawInfo(hokey, max date) ,LawInfo(golf, max date) , LawInfo(basketball, max date)]
Upvotes: 1
Views: 4669
Reputation: 298123
You can use
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()));
});
which will print
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
with your test data. Note that date values in that range are not quite suitable for consistency checks as other dates of this data set may look like having a higher number in printouts because the year is not printed as signed number with this format. I’d recommend to generate dates with reasonable values, e.g. having four digit positive number years…
Upvotes: 3
Reputation: 5558
You could group by two properties (getTextType and getGame), and a max collector.
Something like this:
Map<LawInfoType, Map<Game, Optional<LawInfo>>> map0 = list.stream().collect(
Collectors.groupingBy(LawInfo::getTextType,
Collectors.groupingBy(LawInfo::getGame,
Collectors.maxBy(Comparator.comparing(LawInfo::getMinDate))
)));
Upvotes: 1