Well, it's pretty ugly, but we can do it with stream if you have a List of Booking
class Booking { LocalDate start; LocalDate end; }
and we have a List
List<Booking> bookings = new ArrayList<>(); bookings.add(new Booking(LocalDate.of(2016, 10, 12),LocalDate.of(2016, 10, 18))); bookings.add(new Booking(LocalDate.of(2016, 10, 11),LocalDate.of(2016, 10, 15))); bookings.add(new Booking(LocalDate.of(2016, 10, 13),LocalDate.of(2016, 10, 14))); bookings.add(new Booking(LocalDate.of(2016, 10, 12),LocalDate.of(2016, 10, 13)));
Now we can iterate over the list and for each reservation get all dates from start to end :
Stream<LocalDate> dateRanges = bookings.stream().flatMap(booking -> Stream.iterate(booking.start, d -> d.plusDays(1)) .limit(ChronoUnit.DAYS.between(booking.start, booking.end) + 1) );
We have all the dates, let's calculate how many times each date appears in a new stream.
Map<LocalDate, Long> datesFrequency = dateRanges.peek(System.out::println). collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
and finally, find the maxim - the most common date:
Optional<Map.Entry<LocalDate, Long>> mostFrequent = datesFrequency.entrySet(). stream().max((o1, o2) -> o1.getValue().compareTo(o2.getValue()));
In this case, the result will be optional [2016-10-13 = 4];