我有一个List<Person>
,并且想检查所有人是否都相同。TypePerson
。在这种情况下,这是根据年龄得出的。如果所有相同,则返回该通用类型。
以下方法可以工作,但我认为将人类型首先收集到集合中并不是最佳选择,然后仅返回其中的第一个元素。可以优化以下内容吗?
class Person {
int age;
}
enum TypePerson {
BABY, CHILD, ADULT;
}
//should check if the list contains only a single person type, and return it.
TypePerson reduceToSinglePersonType(List<Person> persons) {
Set<TypePerson> types = persons.stream()
.map(p -> resolvePersonType(person.age))
.collect(Collectors.toSet());
if (types.size() != 1) return null; //nothing in common
return types.iterator().next();
}
TypePerson resolvePersonType(int age) {
if (age < 2) return BABY;
if (age < 10) return CHILD;
return ADULT;
}
答案 0 :(得分:2)
如果只需要(仅)减少值,则无需构建集合。只需将所有项目与列表中第一项的值进行比较,如果全部匹配,则将其返回:
if (!persons.isEmpty()) {
// get the first (only?) person type
TypePerson possiblyOnlyType = resolvePersonType(persons.get(0).age);
// if all items in list have same value...
if (persons.stream()
.allMatch(person -> resolvePersonType(person.age) == possiblyOnlyType)) {
return possiblyOnlyType;
}
}
return null;
答案 1 :(得分:2)
如果可以的话,那将是完美的
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);
}
答案 2 :(得分:0)
TypePerson reduceToSinglePersonType(List<Person> persons) {
if (persons.size() == 0) return null; // no type at all
// the type, if the rest are of the same type
TypePerson candidate = resolvePersonType(persons.get(0).age);
// check whether other persons are of same type
for (int i=1; i<persons.size(); i++) {
if (resolvePersonType(persons.get(1).age) != candidate) return null; // candidate type is not unique
}
return candidate;
}