我有一个Person
的列表。
我想找到一个人要么有工作与最大年龄,否则返回任何人与最大年龄。
我写了下面一段代码。
这样可以吗?还是可以有更好的方法?
List <Person> personList;
Person person = personList.stream()
.filter(p -> p.isEmployed())
.max(Comparator.comparing(Person::getAge))
.orElse(personList.stream()
.max(Comparator.comparing(Person::getAge))
.orElse(null));
我有一个Person列表。我想找一个人,要么有最高年龄的工作,要么返回最高年龄的人。
可以通过创建中间映射,使用收集器partioningBy()
并提供收集器maxBy()
作为下游,以单次通过通过列表来完成。
这个组合将创建一个映射,其中包含两个条目,键为false
和true
,值类型为Optional<Person>
。因为maxBy()
产生一个可选的结果。
首先,我们必须通过应用filter()
来摆脱空的可选项。
true
将排在false
之前(自然顺序:false -> true
)。即就业者年龄最大的人优先。
最后一步是应用findFirst()
并从结果映射项中提取值。
因为我们只对两个条目进行排序,所以它不会造成任何实际的开销,并且代码将运行线性时间(提醒:maxBy()
在O(n)中运行)时间,执行一次遍历数据集)。
List<Person> personList =
List.of(new Person(23, false), new Person(32, true),
new Person(36, true), new Person(39, false),
new Person(19, false), new Person(21, true));
Person person = personList.stream()
.collect(Collectors.partitioningBy(Person::isEmployed, // intermediate map Map<Boolean, Optional<Person>>
Collectors.maxBy(Comparator.comparing(Person::getAge))))
.entrySet().stream()
.filter(entry -> entry.getValue().isPresent())
.sorted(Map.Entry.<Boolean, Optional<Person>>comparingByKey().reversed())
.findFirst() // Optional<Map.Entry<Boolean, Optional<Person>>>
.map(Map.Entry::getValue) // Optional<Optional<Person>>
.map(Optional::get) // Optional<Person>
.orElse(null);
System.out.println(person);
输出:
Person { age = 36, isEmployed = true }
在线演示的链接