一、方法引用
方法引用:若lambda 体中得内容已经有方法实现了,我们可以使用方法引用(可以理解为方法引用为lambda表达式得另一种表现形式)
@Test
public void test1() {
Consumer<String> con = (x) -> System.out.println(x);
//下面这种写法与上面写法效果一致
PrintStream pr = System.out;
Consumer<String> con1 = pr :: println;
}
要想使用方法引用,就必须实现得方法得返回值和参数与函数式接口中得返回值和参数所一致。
我们来看下java8中内置得Consumer接口中得accept方法。
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
我们再看下println方法。
/**
* Prints a String and then terminate the line. This method behaves as
* though it invokes <code>{@link #print(String)}</code> and then
* <code>{@link #println()}</code>.
*
* @param x The <code>String</code> to be printed.
*/
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
因为他们得返回值一致,参数也一致,所以可以这样使用方法引用。
@Test
public void test2() {
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
int b = com.compare(5, 6);
Comparator<Integer> com1 = Integer :: compare;
int c = com1.compare(7, 8);
}
如果是静态方法的话,首先也是要返回值和参数与Comparator中的compare方法得一致,然后可以直接使用类名 :: 方法名去引用这个方法。上面得接口中得实现已经由Integer中得compare方法实现了,而且两个方法得返回值与参数都一致,所以,可以这样 使用。
@Test
public void test3() {
BiPredicate<String, String> bi = (x, y) -> x.equals(y);
BiPredicate<String, String> bi1 = String :: equals;
}
这类引用就比较特殊了,这类引用要求第一个入参的类型必须时调用方法的实例,第二二个参数必须时方法得参数才可以使用这种类型得引用。
二、构造器引用
格式: ClassName :: new
@Test
public void test4() {
Supplier<Encoder> su = () -> new Encoder();
Supplier<Encoder> su1 = Encoder :: new;
}
上面是调用无参构造器
@Test
public void test5() {
Function<Integer, Integer> fun = (x) -> new Integer(x);
Function<Integer, Integer> fun1 = Integer :: new;
}
上面是调用有参构造器。
上面得2个方法调用什么构造器,主要取决于函数式接口中参数得个数和类型。
三、数组引用
格式 :Type :: new
@Test
public void test6() {
Function<Integer, String[]> fun = (x) -> new String[x];
Function<Integer, String[]> fun1 = String[] :: new;
}
用上面的方式,我们可以快速地创建数组。