如何使用流编译具有给定属性最大值的所有对象的列表?

时间:2019-02-08 12:19:21

标签: java max java-stream filtering

说我有一个People列表,其中包含属性名称和年龄。如何使用流获取所有People个属性年龄最大的实例?

当前,我正在使用两步方法:

1)寻找年龄的最大值

int maxAge = group
        .stream()
        .mapToInt(person -> person.getAge())
        .max()
        .orElse(-1);

2)创建一个具有该年龄的People列表

List<Group> groupWithMaxAge = group
        .stream()
        .filter(person -> person.getAge() == maxAge)
        .collect(Collectors.toList());

不用担心,这行得通。但是,请考虑以下情况:计算年龄是一项昂贵的功能。在那种情况下,如果您可以一口气做到这一点,那会很好,不是吗?

3 个答案:

答案 0 :(得分:4)

您还可以将groupingBy与TreeMap一起用作mapFactory:

List<Group> list = people.stream()
            .collect(groupingBy(Group::getAge, TreeMap::new, toList()))
            .lastEntry()
            .getValue();

答案 1 :(得分:2)

一种更清洁的方法是将Stream.max用作:

List<Group> groupWithMaxAge = group.stream() // Stream<Group>
    .collect(Collectors.groupingBy(Group::getAge)) // Map<Integer, List<Group>
    .entrySet() // Set<Entry<Integer, List<Group>>>
    .stream().max(Comparator.comparingInt(Entry::getKey)) // Optional<Entry<Integer, List<Group>>>
    .map(Entry::getValue) // Optional<List<Person>>
    .orElse(new ArrayList<>());

答案 2 :(得分:1)

另一种方法是对最大键(age)进行分组和选择:

List<People> peopleWithMaxAge = group.stream()
        .collect(Collectors.groupingBy(People::getAge))
        .entrySet()
        .stream()
        .sorted(Comparator.<Entry<Integer, List<People>>>comparingInt(Entry::getKey)
                .reversed())
        .findFirst()
        .map(Entry::getValue)
        .orElse(new ArrayList<>()); //empty list if original was empty