import java.time.*;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main
(String args
[]) { List
<Item
> items
= Arrays.
asList( new Item(LocalDateTime.parse("2020-08-21T00:00:00"), LocalDateTime.parse("2020-08-21T00:02:00"), "item1"),
new Item(LocalDateTime.parse("2020-08-21T00:01:00"), LocalDateTime.parse("2020-08-21T00:03:00"), "item2"),
new Item(LocalDateTime.parse("2020-08-21T00:03:00"), LocalDateTime.parse("2020-08-21T00:07:00"), "item3"),
new Item(LocalDateTime.parse("2020-08-21T00:04:00"), LocalDateTime.parse("2020-08-21T00:12:00"), "item4"),
new Item(LocalDateTime.parse("2020-08-21T09:50:37"), LocalDateTime.parse("2020-08-21T09:56:49"), "item5"),
new Item(LocalDateTime.parse("2020-08-21T09:59:37"), LocalDateTime.parse("2020-08-21T10:02:37"), "item6"),
new Item(LocalDateTime.parse("2020-08-21T09:49:37"), LocalDateTime.parse("2020-08-21T09:51:37"), "item7"),
new Item(LocalDateTime.parse("2019-12-31T23:59:37"), LocalDateTime.parse("2020-01-01T00:03:37"), "item8"),
new Item(LocalDateTime.parse("2020-01-01T00:04:37"), LocalDateTime.parse("2020-01-01T00:06:37"), "item9"),
// added to test a single entry within 5 min range
new Item(LocalDateTime.parse("2020-01-01T00:42:37"), LocalDateTime.parse("2020-01-01T00:44:37"), "item10")
);
items.stream()
.flatMap(Main::convert)
.collect(Collectors.groupingBy(x -> x.getKey(), LinkedHashMap::new, Collectors.mapping(x -> x.getValue(), Collectors.toList())))
.entrySet().stream()
.filter(x -> x.getValue().size() > 1)
.
forEach(System.
out::println
); }
public static Stream
<Map.
Entry<String, Item
>> convert
(Item item
) { LocalDateTime start = getKey(item.getStartTime());
LocalDateTime end = getKey(item.getEndTime()).plusMinutes(5);
return Stream
.iterate(start, d -> d.plusMinutes(5))
.limit(ChronoUnit.MINUTES.between(start, end) / 5)
.
map(d
-> new AbstractMap.
SimpleEntry(d
+ "**" + d.
plusMinutes(5), item
)); }
public static LocalDateTime getKey(LocalDateTime time) {
return LocalDateTime.of(time.getYear(), time.getMonthValue(), time.getDayOfMonth(), time.getHour(), time.getMinute() - time.getMinute() % 5);
}
}
class Item {
final LocalDateTime startTime;
final LocalDateTime endTime;
public Item
(LocalDateTime s, LocalDateTime e,
String n
) { startTime = s;
endTime = e;
name = n;
}
public LocalDateTime getStartTime() {return startTime;}
public LocalDateTime getEndTime() {return endTime;}
public String getName
() {return name
;} @Override
return name;
//return "{ " + String.join(", ", name, startTime.toString(), endTime.toString()) + " }";
}
}
aW1wb3J0IGphdmEudGltZS4qOwppbXBvcnQgamF2YS50aW1lLnRlbXBvcmFsLkNocm9ub1VuaXQ7CmltcG9ydCBqYXZhLnV0aWwuKjsKaW1wb3J0IGphdmEudXRpbC5zdHJlYW0uKjsKCnB1YmxpYyBjbGFzcyBNYWluIHsKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZyBhcmdzW10pIHsKICAgICAgICBMaXN0PEl0ZW0+IGl0ZW1zID0gQXJyYXlzLmFzTGlzdCgKICAgICAgICAgICAgbmV3IEl0ZW0oTG9jYWxEYXRlVGltZS5wYXJzZSgiMjAyMC0wOC0yMVQwMDowMDowMCIpLCBMb2NhbERhdGVUaW1lLnBhcnNlKCIyMDIwLTA4LTIxVDAwOjAyOjAwIiksICJpdGVtMSIpLAogICAgICAgICAgICBuZXcgSXRlbShMb2NhbERhdGVUaW1lLnBhcnNlKCIyMDIwLTA4LTIxVDAwOjAxOjAwIiksIExvY2FsRGF0ZVRpbWUucGFyc2UoIjIwMjAtMDgtMjFUMDA6MDM6MDAiKSwgIml0ZW0yIiksCiAgICAgICAgICAgIG5ldyBJdGVtKExvY2FsRGF0ZVRpbWUucGFyc2UoIjIwMjAtMDgtMjFUMDA6MDM6MDAiKSwgTG9jYWxEYXRlVGltZS5wYXJzZSgiMjAyMC0wOC0yMVQwMDowNzowMCIpLCAiaXRlbTMiKSwKICAgICAgICAgICAgbmV3IEl0ZW0oTG9jYWxEYXRlVGltZS5wYXJzZSgiMjAyMC0wOC0yMVQwMDowNDowMCIpLCBMb2NhbERhdGVUaW1lLnBhcnNlKCIyMDIwLTA4LTIxVDAwOjEyOjAwIiksICJpdGVtNCIpLAogICAgICAgICAgICBuZXcgSXRlbShMb2NhbERhdGVUaW1lLnBhcnNlKCIyMDIwLTA4LTIxVDA5OjUwOjM3IiksIExvY2FsRGF0ZVRpbWUucGFyc2UoIjIwMjAtMDgtMjFUMDk6NTY6NDkiKSwgIml0ZW01IiksCiAgICAgICAgICAgIG5ldyBJdGVtKExvY2FsRGF0ZVRpbWUucGFyc2UoIjIwMjAtMDgtMjFUMDk6NTk6MzciKSwgTG9jYWxEYXRlVGltZS5wYXJzZSgiMjAyMC0wOC0yMVQxMDowMjozNyIpLCAiaXRlbTYiKSwKICAgICAgICAgICAgbmV3IEl0ZW0oTG9jYWxEYXRlVGltZS5wYXJzZSgiMjAyMC0wOC0yMVQwOTo0OTozNyIpLCBMb2NhbERhdGVUaW1lLnBhcnNlKCIyMDIwLTA4LTIxVDA5OjUxOjM3IiksICJpdGVtNyIpLAogICAgICAgICAgICBuZXcgSXRlbShMb2NhbERhdGVUaW1lLnBhcnNlKCIyMDE5LTEyLTMxVDIzOjU5OjM3IiksIExvY2FsRGF0ZVRpbWUucGFyc2UoIjIwMjAtMDEtMDFUMDA6MDM6MzciKSwgIml0ZW04IiksCiAgICAgICAgICAgIG5ldyBJdGVtKExvY2FsRGF0ZVRpbWUucGFyc2UoIjIwMjAtMDEtMDFUMDA6MDQ6MzciKSwgTG9jYWxEYXRlVGltZS5wYXJzZSgiMjAyMC0wMS0wMVQwMDowNjozNyIpLCAiaXRlbTkiKSwKICAgICAgICAgICAgLy8gYWRkZWQgdG8gdGVzdCBhIHNpbmdsZSBlbnRyeSB3aXRoaW4gNSBtaW4gcmFuZ2UKICAgICAgICAgICAgbmV3IEl0ZW0oTG9jYWxEYXRlVGltZS5wYXJzZSgiMjAyMC0wMS0wMVQwMDo0MjozNyIpLCBMb2NhbERhdGVUaW1lLnBhcnNlKCIyMDIwLTAxLTAxVDAwOjQ0OjM3IiksICJpdGVtMTAiKQogICAgICAgICk7CgogICAgICAgIGl0ZW1zLnN0cmVhbSgpCiAgICAgICAgICAgICAuZmxhdE1hcChNYWluOjpjb252ZXJ0KQogICAgICAgICAgICAgLmNvbGxlY3QoQ29sbGVjdG9ycy5ncm91cGluZ0J5KHggLT4geC5nZXRLZXkoKSwgTGlua2VkSGFzaE1hcDo6bmV3LCBDb2xsZWN0b3JzLm1hcHBpbmcoeCAtPiB4LmdldFZhbHVlKCksIENvbGxlY3RvcnMudG9MaXN0KCkpKSkKICAgICAgICAgICAgIC5lbnRyeVNldCgpLnN0cmVhbSgpCiAgICAgICAgICAgICAuZmlsdGVyKHggLT4geC5nZXRWYWx1ZSgpLnNpemUoKSA+IDEpCiAgICAgICAgICAgICAuZm9yRWFjaChTeXN0ZW0ub3V0OjpwcmludGxuKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN0cmVhbTxNYXAuRW50cnk8U3RyaW5nLCBJdGVtPj4gY29udmVydChJdGVtIGl0ZW0pIHsKICAgICAgICBMb2NhbERhdGVUaW1lIHN0YXJ0ID0gZ2V0S2V5KGl0ZW0uZ2V0U3RhcnRUaW1lKCkpOwogICAgICAgIExvY2FsRGF0ZVRpbWUgZW5kID0gZ2V0S2V5KGl0ZW0uZ2V0RW5kVGltZSgpKS5wbHVzTWludXRlcyg1KTsKICAgIAogICAgICAgIHJldHVybiBTdHJlYW0KICAgICAgICAgICAgICAgIC5pdGVyYXRlKHN0YXJ0LCBkIC0+IGQucGx1c01pbnV0ZXMoNSkpCiAgICAgICAgICAgICAgICAubGltaXQoQ2hyb25vVW5pdC5NSU5VVEVTLmJldHdlZW4oc3RhcnQsIGVuZCkgLyA1KQogICAgICAgICAgICAgICAgLm1hcChkIC0+IG5ldyBBYnN0cmFjdE1hcC5TaW1wbGVFbnRyeShkICsgIioqIiArIGQucGx1c01pbnV0ZXMoNSksIGl0ZW0pKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIExvY2FsRGF0ZVRpbWUgZ2V0S2V5KExvY2FsRGF0ZVRpbWUgdGltZSkgewogICAgICAgIHJldHVybiBMb2NhbERhdGVUaW1lLm9mKHRpbWUuZ2V0WWVhcigpLCB0aW1lLmdldE1vbnRoVmFsdWUoKSwgdGltZS5nZXREYXlPZk1vbnRoKCksIHRpbWUuZ2V0SG91cigpLCB0aW1lLmdldE1pbnV0ZSgpIC0gdGltZS5nZXRNaW51dGUoKSAlIDUpOwogICAgfQp9CgpjbGFzcyBJdGVtIHsKICAgIGZpbmFsIExvY2FsRGF0ZVRpbWUgc3RhcnRUaW1lOwogICAgZmluYWwgTG9jYWxEYXRlVGltZSBlbmRUaW1lOwogICAgZmluYWwgU3RyaW5nIG5hbWU7CgogICAgcHVibGljIEl0ZW0oTG9jYWxEYXRlVGltZSBzLCBMb2NhbERhdGVUaW1lIGUsIFN0cmluZyBuKSB7CiAgICAgICAgc3RhcnRUaW1lID0gczsKICAgICAgICBlbmRUaW1lID0gZTsKICAgICAgICBuYW1lID0gbjsKICAgIH0KICAgIAogICAgcHVibGljIExvY2FsRGF0ZVRpbWUgZ2V0U3RhcnRUaW1lKCkge3JldHVybiBzdGFydFRpbWU7fQogICAgcHVibGljIExvY2FsRGF0ZVRpbWUgZ2V0RW5kVGltZSgpIHtyZXR1cm4gZW5kVGltZTt9CiAgICBwdWJsaWMgU3RyaW5nIGdldE5hbWUoKSB7cmV0dXJuIG5hbWU7fQogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCkgewogICAgICAgIHJldHVybiBuYW1lOwogICAgICAgIC8vcmV0dXJuICJ7ICIgKyBTdHJpbmcuam9pbigiLCAiLCBuYW1lLCBzdGFydFRpbWUudG9TdHJpbmcoKSwgZW5kVGltZS50b1N0cmluZygpKSArICIgfSI7CiAgICB9Cn0=