乐趣区

关于spring:Java-8-中的方法引用轻松减少代码量提升可读性

1. 引言

Java8 中最受宽广开发中喜爱的变动之一是因为引入了 lambda 表达式,因为这些表达式容许咱们放弃匿名类,从而大大减少了样板代码,并进步了可读性。
办法援用是 lambda 表达式的一种非凡类型。它们通常通过援用现有办法来创立简略的 lambda 表达式。

办法援用包含以下四种类型:

  • 静态方法
  • 特定对象的实例办法
  • 特定类型的任意对象的实例办法
  • 构造方法

在本篇文章中,咱们将探讨 Java 中的办法援用。

2. 援用静态方法

We’ll begin with a very simple example, capitalizing and printing a list of Strings:

咱们从一个非常简单的示例开始,字符串转成大写并打印:

List<String> messages = Arrays.asList("hello", "baeldung", "readers!");

咱们能够通过简略的 lambda 表达式间接调用 StringUtils.capitalize() 办法:

messages.forEach(word -> StringUtils.capitalize(word));

或者,咱们能够应用办法援用来简略地援用 capitalize 静态方法:

messages.forEach(StringUtils::capitalize);

留神,办法援用应应用 :: 运算符。

3. 援用特定对象的实例办法

为了演示这种类型的办法援用,咱们新建以下这两个类:

public class Bicycle {
 
    private String brand;
    private Integer frameSize;
    // standard constructor, getters and setters
}
 
public class BicycleComparator implements Comparator {
 
    @Override
    public int compare(Bicycle a, Bicycle b) {return a.getFrameSize().compareTo(b.getFrameSize());
    }
 
}

创立一个 BicycleComparator 对象来比拟自行车尺寸:

BicycleComparator bikeFrameSizeComparator = new BicycleComparator();

咱们能够应用 lambda 表达式按尺寸大小对自行车进行排序,但须要指定两个自行车实例进行比拟:

createBicyclesList().stream()
  .sorted((a, b) -> bikeFrameSizeComparator.compare(a, b));

咱们能够应用办法援用让编译器把句柄参数传递给咱们:

createBicyclesList().stream()
  .sorted(bikeFrameSizeComparator::compare);

4. 援用特定类型任意对象的实例办法

这种类型的办法援用与后面的示例相似,但不用创立自定义对象来执行比拟。

让咱们创立一个要排序的Integer 整数列表:

List<Integer> numbers = Arrays.asList(5, 3, 50, 24, 40, 2, 9, 18);

如果咱们应用经典的 lambda 表达式,这两个参数都须要显式传递,而应用办法援用则要简略得多:

numbers.stream()
  .sorted((a, b) -> a.compareTo(b));
numbers.stream()
  .sorted(Integer::compareTo);

只管它依然是一行代码,然而办法援用更容易浏览和了解。

5. 援用构造函数

咱们能够像在第一个例子中援用静态方法一样援用构造函数。惟一区别是须要应用 new 关键字。
当初咱们用不同品牌的 String 列表创立一个 Bicycle 数组:

List<String> bikeBrands = Arrays.asList("Giant", "Scott", "Trek", "GT");

首先,咱们将向 Bicycle 类增加一个新的构造函数:

public Bicycle(String brand) {
    this.brand = brand;
    this.frameSize = 0;
}

接下来,咱们将应用办法援用中的新构造函数,并从原始的 String 列表中生成一个 Bicycle 数组:

bikeBrands.stream()
  .map(Bicycle::new)
  .toArray(Bicycle[]::new);

留神如何应用办法援用调用 BicycleArray构造函数,从而使代码看起来更加简洁明了。

6. 其余示例和限度

目前为止,办法援用是一个使代码十分清晰和易读的好办法。然而,咱们不能用它们来代替各种 lambda 表达式,因为它们有一些局限性。

它们的次要局限性是因为它们最大的长处:前一个表达式的输入须要与援用的办法申明的输出参数匹配

看看这个限度的例子:

createBicyclesList().forEach(b -> System.out.printf(
  "Bike brand is'%s'and frame size is'%d'%n",
  b.getBrand(),
  b.getFrameSize()));

这个简略的例子不能用办法援用来示意,因为在咱们的例子中,printf 办法须要 3 个参数,而应用 createBicyclesList().forEach() 只容许办法援用一个参数(Bicycle对象)。

最初,咱们钻研下,如何创立一个能够从 lambda 表达式援用的 no-operation 函数。

在本例中,咱们心愿应用 lambda 表达式而不应用其参数。

首先,创立 doNothingAtAll 办法:

private static <T> void doNothingAtAll(Object... o) {}

因为这是一个 varargs 办法,它可执行在任意 lambda 表达式中,而不论援用的对象或参数的数量。咱们看看它的作用:

createBicyclesList()
  .forEach((o) -> MethodReferenceExamples.doNothingAtAll(o));

7. 总结

在这篇文章中,咱们学习了 Java 中的办法援用,以及如何应用它们来替换 lambda 表达式,从而进步了可读性并说明编程的用意。

如果你感觉文章还不错,记得关注公众号:锅外的大佬
锅外的大佬博客

退出移动版