This will incur an overhead of creating a set but it's simple and will work correctly even if you forget to distinct() the stream first.
static Collector> singleOrEmpty() {
return Collectors.collectingAndThen(
Collectors.toSet(),
set -> set.size() == 1
? set.stream().findAny()
: Optional.empty()
);
}