Было бы идеально, если бы мы могли сделать
TypePerson reduceToSinglePersonType(List<Person> persons) {
return persons.stream()
.map(p -> resolvePersonType(p.age))
.reduce((t1, t2) -> t1 == t2? t1: null) // does not work
.orElse(null);
}
, но, к сожалению, для reduce
не допускается оценка до null
, и поскольку тип является enum
, нетдругое значение вне допустимого диапазона для представления недопустимого состояния с неоднозначными значениями.
Один обходной путь будет иметь дело с порядковыми номерами, которые позволяют нам использовать -1
в качестве недопустимого значения
TypePerson reduceToSinglePersonType(List<Person> persons) {
int o = persons.stream()
.mapToInt(p -> resolvePersonType(p.age).ordinal())
.reduce((t1, t2) -> t1 == t2? t1: -1)
.orElse(-1);
return o < 0? null: TypePerson.values()[o];
}
Или мы используем Optional
, который действительно поддерживает отсутствующие значения
TypePerson reduceToSinglePersonType(List<Person> persons) {
return persons.stream()
.map(p -> Optional.of(resolvePersonType(p.age)))
.reduce((o1, o2) -> o1.equals(o2)? o1: Optional.empty())
.flatMap(Function.identity())
.orElse(null);
}
Или мы временно отказываемся от безопасности типов, чтобы иметь возможность использовать объект другого типа для представления недопустимого состояния
TypePerson reduceToSinglePersonType(List<Person> persons) {
return persons.stream()
.<Object>map(p -> resolvePersonType(p.age))
.reduce((o1, o2) -> o1 == o2? o1: "invalid")
.filter(o -> o != "invalid")
.map(TypePerson.class::cast)
.orElse(null);
}