Java方法引用类型和示例

时间:2020-02-23 14:36:42  来源:igfitidea点击:

Java方法引用与lambda表达式一起在Java 8中引入。
方法引用是在调用方法时创建lambda表达式的快捷方式。

什么是Java方法引用?

方法参考允许我们从现有方法创建lambda表达式。
当lambda表达式调用函数而不做其他任何事情时使用。
JVM通过将输入变量映射到方法参数来创建lambda表达式。

方法引用语法

方法参考包括两部分-类/对象和方法/构造函数。
它们之间用双冒号(::)分隔。
方法引用没有传递其他参数。

方法引用的类型

Java中有四种类型的方法引用。

  • 静态方法参考:其语法为Class :: StaticMethodName
  • 引用对象实例方法:语法为Object :: instanceMethodName
  • 引用特定类型的任意对象的实例方法:语法为Class :: instanceMethodName
  • 构造函数参考:其语法为ClassName :: new

Java方法引用示例

让我们看一下所有四种方法引用的示例。
我们将首先创建一个lambda表达式,然后使用方法引用产生相同的效果。

1.静态方法引用

假设我们具有以下函数接口。

@FunctionalInterface
interface Counter {
	int count(Object[] objArray);
}

我们有一个Utils类来获取数组中元素的数量。

class Utils {

	public static int countElements(Object[] array) {
		return array.length;
	}
}

我们将使用lambda表达式调用Utils类的countElements()方法以获取数组中的元素数。

Integer[] intArray = { 1, 2, 3, 4, 5 };

//lambda expression
Counter counter2 = array -> Utils.countElements(array);

System.out.println(counter2.count(intArray)); //5

其中lambda表达式只是调用Utils类的静态方法,而不做其他任何事情。
这是使用方法引用调用静态方法的理想场所。

Counter counter = Utils::countElements;

2.对象实例方法引用

让我们更改Utils类的实现,并创建一个实例方法。

class Utils {

	public int count(Object[] array) {
		return array.length;
	}
}

现在,我们将创建一个lambda表达式来调用此实例方法。

Utils ut = new Utils();
		
Counter counter1 = array -> ut.count(array);

我们可以将lambda表达式替换为实例方法参考。

Counter counter1 = ut::count;

我们可以在方法引用本身中实例化Utils类。

Counter counter1 = new Utils()::count;

3.引用任意对象的实例方法

有时,我们在lambda表达式中调用参数的方法。
在这种情况下,我们可以使用方法引用来调用特定类型的任意对象的实例方法。

假设我们有一个这样的lambda表达式。

String[] strArray = { "A", "E", "I", "O", "U", "a", "e", "i", "o", "u" };

Arrays.sort(strArray, (s1, s2) -> s1.compareToIgnoreCase(s2));

其中lambda表达式只是调用一个方法。
因此,我们可以在此处使用方法参考。
但是,该方法在String的任意对象上调用。
因此,我们可以通过引用String类来调用实例方法。

Arrays.sort(strArray, String::compareToIgnoreCase);

4.构造方法引用

Stream collect()方法接受Supplier参数。
供应商应每次返回一个新实例。
因此,lambda表达式必须调用构造函数。
让我们看一个简单的例子。

List<Integer> intList = List.of(1, 2, 3, 4, 5);

String concat1 = intList.parallelStream().collect(
		() -> new StringBuilder(),
		(x, y) -> x.append(y),
		(a, b) -> a.append(b)).toString();

其中我们可以将"()-> new StringBuilder()"替换为构造函数方法参考。

String concat1 = intList.parallelStream().collect(
		StringBuilder::new,
		(x, y) -> x.append(y),
		(a, b) -> a.append(b)).toString();

好吧,我们不必在这里停下来。
其他两个lambda表达式也可以用方法引用代替。

String concat1 = intList.parallelStream().collect(
		StringBuilder::new,
		StringBuilder::append,
		StringBuilder::append).toString();