Java方法引用类型和示例
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();