Java方法引用:优雅的代码之道-二:具体说明

Java中的方法引用主要有以下四种类型:1. 静态方法引用格式为  类名::静态方法名  。当需要引用一个类的静态方法时,就可以使用这种形式。例如,对于  Math  类中的  abs  静态方法,可以这样引用:

<1>javaComparator<Integer> comparator = Integer::compare

这 里  Integer::compare  就是对  Integer  类的静态方法  compare  的引用。2. 实例方法引用格式为  对象名::实例方法名  。当需要引用某个特定对象的实例方法时,可以使用这种形式。例如,有一个  User  类,其中有一个  getName  实例方法:

javaComparator<Integer> comparator = Integer::compare;

这里  Integer::compare  就是对  Integer  类的静态方法  compare  的引用。

<2>实例方法引用

格式为  对象名::实例方法名  。当需要引用某个特定对象的实例方法时,可以使用这种形式。例如,有一个  User  类,其中有一个  getName  实例方法:

class User {
    private String name;
    public User(String name) { this.name = name; }
    public String getName() { return name; }
}

User user = new User("Kimi");
Function<User, String> getNameFunction = user::getName;

这里  user::getName  就是对  user  对象的  getName  实例方法的引用。

<3>类方法引用

格式为  类名::实例方法名  。这种引用方式适用于方法的调用者是通过参数传递进来的对象。例如,对于  String  类的  length  方法:

Function<String, Integer> lengthFunction = String::length;

这里  String::length  表示引用  String  类对象的  length  方法,调用时会传入一个  String  对象作为方法的调用者。

<5>构造方法引用

格式为  类名::new  。当需要引用一个类的构造方法时,可以使用这种形式。例如,引用  ArrayList  类的无参构造方法:

javaSupplier<ArrayList> arrayListSupplier = ArrayList::new;

这里  ArrayList::new  就是对  ArrayList  类无参构造方法的引用。

三:方法引用的案例

静态方法引用案例:排序优化假设有一个  Employee  类,其中包含员工的姓名和年龄属性:

javaclass Employee {

    private String name;

    private int age;

    public Employee(String name, int age) {

        this.name = name;

        this.age = age;

    }

    public String getName() { return name; }

    public int getAge() { return age; }

}

现在有一个  Employee  对象列表,需要按照年龄进行排序。在Java 8之前,我们可能会这样写:

javaList<Employee> employees = Arrays.asList(new Employee("Alice", 30), new Employee("Bob", 25), new Employee("Charlie", 35));

Collections.sort(employees, new Comparator<Employee>() {

    @Override

    public int compare(Employee e1, Employee e2) {

        return Integer.compare(e1.getAge(), e2.getAge());

    }
    });

    使用Lambda表达式后,可以简化为:

javaemployees.sort((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));

而使用静态方法引用,代码可以进一步简化为:

javaemployees.sort(Comparator.comparingInt(Employee::getAge));

这里  Comparator.comparingInt(Employee::getAge)  利用了  Comparator  类的  comparingInt  静态方法,通过方法引用  Employee::getAge  来获取员工年龄,然后进行比较排序。这种方式不仅代码更加简洁,而且可读性也更高。2. 实例方法引用案例:数据处理假设有一个  Order  类,表示订单,其中包含订单号和订单金额属性:javaclass Order {

 

private String orderId;

    private double amount;

    public Order(String orderId, double amount) {

        this.orderId = orderId;

        this.amount = amount;

    }

    public String getOrderId() { return orderId; }

    public double getAmount() { return amount; }

}

现在有一个订单列表,需要将订单号提取出来存放到一个新的列表中。传统的方式可能是这样:

javaList<Order> orders = Arrays.asList(new Order("1001", 120.5), new Order("1002", 80.0), new Order("1003", 200.0));

List<String> orderIds = new ArrayList<>();

for (Order order : orders) {

    orderIds.add(order.getOrderId());

}

使用Lambda表达式可以简化为:

javaList<String> orderIds = orders.stream().map(order -> order.getOrderId()).collect(Collectors.toList());

而使用实例方法引用,代码可以更简洁地写为:

avaList<String> orderIds = orders.stream().map(Order::getOrderId).collect(Collectors.toList());

这里  Order::getOrderId  直接引用了  Order  类对象的  getOrderId  实例方法,通过流的操作将订单列表中的每个订单的订单号提取出来,最终收集到一个新的列表中。这种方式使得代码更加优雅,也更易于理解和维护3. 类方法引用案例:字符串处理假设有一个字符串列表,需要对其中的每个字符串进行去空格操作。

传统的方式可能是这样:

javaList<String> strings = Arrays.asList(" hello ", " world ", " java ");

List<String> trimmedStrings = new ArrayList<>();

for (String str : strings) {

    trimmedStrings.add(str.trim());

}

使用Lambda表达式可以简化为:

javaList<String> trimmedStrings = strings.stream().map(str -> str.trim()).collect(Collectors.toList());

而使用类方法引用,代码可以更简洁地写为:

javaList<String> trimmedStrings = strings.stream().map(String::trim).collect(Collectors.toList());

这里  String::trim  引用了  String  类对象的  trim  方法,通过流的操作对字符串列表中的每个字符串进行去空格处理,最终收集到一个新的列表中。这种方式不仅减少了代码量,而且使得代码的意图更加明确。

  1. 构造方法引用案例:

对象创建假设有一个  Product  类,表示产品,其中包含产品名称和价格属性:javaclass Product {

private String name;

    private double price;

    public Product(String name, double price) {

        this.name = name;

        this.price = price;

    }

    public String getName() { return name; }

    public double getPrice() { return price; }

}

现在有一个包含产品名称和价格的二维数组,需要根据这些数据创建  Product  对象列表。传统的方式可能是这样:

javaString[][] productData = {{"Apple", "10.0"}, {"Banana", "5.0"}, {"Orange", "8.0"}};

List<Product> products = new ArrayList<>();

for (String[] data : productData) {

    products.add(new Product(data[0], Double.parseDouble(data[1])));

}

使用Lambda表达式可以简化为:

javaList<Product> products = Arrays.stream(productData).map(data -> new Product(data[0], Double.parseDouble(data[1]))).collect(Collectors.toList());

而使用构造方法引用,代码可以更简洁地写为:

javaList<Product> products = Arrays.stream(productData).map(data -> new Product(data[0], Double.parseDouble(data[1]))).collect(Collectors.toList());

这里  Product::new  引用了  Product  类的构造方法,通过流的操作将二维数组中的每个数据项转换为  Product  对象,最终收集到一个新的列表中。这种方式使得对象的创建过程更加简洁明了。

四:总结

代码简洁:方法引用能够让代码更加简洁,减少冗余的代码,提高代码的可读性和可维护性。

  1. 语义清晰:方法引用的语法直观地表达了调用某个方法的意图,使得代码的语义更加清晰,易于理解。
  2. 性能优化:在某些情况下,方法引用可能会比Lambda表达式有更好的性能表现,因为方法引用在编译时就已经确定了具体的调用方法,而Lambda表达式可能需要在运行时进行更多的动态解析。局限性1. 适用场景有限:方法引用只能用于那些符合函数式接口方法签名的场景,如果方法的参数类型、返回类型等与函数式接口不匹配,就无法使用方法引用。2. 灵活性较低:与Lambda表达式相比,方法引用的灵活性较低。Lambda表达式可以包含任意的逻辑,而方法引用只能引用已有的方法,无法在引用时添加额外的逻辑处理。









上一篇:有了小浣熊,我就是“古希腊掌管效率的神”


下一篇:现代谱估计的原理及MATLAB仿真(二)(AR模型法、MVDR法、MUSIC法)-前言