Java 查找最大值和最小值

Java 查找最大值和最小值,用户希望确定流中的最大值或最小值,既可以使用 BinaryOperator 接口定义的 maxByminBy 方法,也可以使用 Stream 接口定义的 maxmin 方法,还可以使用 Collectors 类定义的 maxByminBy 方法。

Java 查找最大值和最小值 问题描述

用户希望确定流中的最大值或最小值。

Java 查找最大值和最小值 解决方案

既可以使用 BinaryOperator 接口定义的 maxByminBy 方法,也可以使用 Stream 接口定义的 maxmin 方法,还可以使用 Collectors 类定义的 maxByminBy 方法。

Java 查找最大值和最小值 具体实例

BinaryOperatorjava.util.function 包定义的一种函数式接口,它继承自 BiFunction 接口,适合在函数和返回值的参数属于同一个类时使用。
BinaryOperator 接口包括两种静态方法:

static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator)
static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator)

两种方法根据所提供的 Comparator,返回一个 BinaryOperator
我们以一个 Employee POJO 为例,讨论如何获取流的最大值。如例 4-24 所示,Employee POJO 包括 namesalarydepartment 这三个特性。

例 4-24 Employee POJO

public class Employee {
    private String name;
    private Integer salary;
    private String department;

    // 其他方法
}

List<Employee> employees = Arrays.asList(                 ➊
        new Employee("Cersei",     250_000, "Lannister"),
        new Employee("Jamie",      150_000, "Lannister"),
        new Employee("Tyrion",       1_000, "Lannister"),
        new Employee("Tywin",    1_000_000, "Lannister"),
        new Employee("Jon Snow",    75_000, "Stark"),
        new Employee("Robb",       120_000, "Stark"),
        new Employee("Eddard",     125_000, "Stark"),
        new Employee("Sansa",            0, "Stark"),
        new Employee("Arya",         1_000, "Stark"));

Employee defaultEmployee =                                ➋
    new Employee("A man (or woman) has no name", 0, "Black and White");

❶ 员工集合
❷ 流为空时的默认值
给定一个由员工构成的集合,可以使用 Stream.reduce 方法,传入 BinaryOperator 作为参数。例 4-25 展示了如何查找工资最高的员工信息。

例 4-25 BinaryOperator.maxBy 方法的应用

Optional<Employee> optionalEmp = employees.stream()
    .reduce(BinaryOperator.maxBy(Comparator.comparingInt(Employee::getSalary)));

System.out.println("Emp with max salary: " +
    optionalEmp.orElse(defaultEmployee));

请注意,reduce 方法需要传入 BinaryOperator 作为参数。静态方法 maxBy 根据所提供的 Comparator 生成该 BinaryOperator,并按工资高低对员工进行比较。
上述方案是可行的,不过采用 Stream.max 方法其实更简单,该方法可以直接应用于流:

Optional<T> max(Comparator<? super T> comparator)

例 4-26 显示了 max 方法的应用。

例 4-26 Stream.max 方法的应用

optionalEmp = employees.stream()
        .max(Comparator.comparingInt(Employee::getSalary));

Stream.max 方法与 BinaryOperator.maxBy 方法的结果并无不同。
此外,几种基本类型流(IntStreamLongStreamDoubleStream)也提供一个不传入任何参数的 max 方法,其应用如例 4-27 所示。

例 4-27 查找最高工资

OptionalInt maxSalary = employees.stream()
        .mapToInt(Employee::getSalary)
        .max();
System.out.println("The max salary is " + maxSalary);

在本例中,mapToInt 方法通过调用 getSalary 方法将员工流转换为整数流,并返回 IntStream。之后,Max 方法返回 OptionalInt
类似地,Collectors 工具类也定义了一种称为 maxBy 的静态方法,可以直接用于查找最高工资,如例 4-28 所示。

例 4-28 Collectors.maxBy 方法的应用

optionalEmp = employees.stream()
    .collect(Collectors.maxBy(Comparator.comparingInt(Employee::getSalary)));

但是,Collectors.maxBy 方法不便处理,最好采用 Stream.max 方法作为替代(如例 4-27 所示)。Collectors.maxBy 方法在用作下游收集器(即对分组或分区操作进行后期处理)时相当有用。例 4-29 通过 Collectors.groupingBy 方法创建了一个部门到员工列表的映射,然后计算每个部门中工资最高的员工。

例 4-29 Collectors.maxBy 用作下游收集器

Map<String, Optional<Employee>> map = employees.stream()
    .collect(Collectors.groupingBy(
                Employee::getDepartment,
                Collectors.maxBy(
                    Comparator.comparingInt(Employee::getSalary))));

map.forEach((house, emp) ->
        System.out.println(house + ": " + emp.orElse(defaultEmployee)));

BinaryOperator.minByCollectors.minBy 方法的用法与相应的 maxBy 方法类似。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程