Java新特性-方法引用
  TEZNKK3IfmPf 16天前 22 0

在使用 Lambda 表达式的时候,我们实际上传递进去的代码就是一种解决方案:拿参数做操作, 如果我们在 Lambda 中所指定的操作方案,已经有地方存在相同方案, 就可以通过方法引用来使用已经存在的方案

体验方法的引用

新建一个 ​​Printable​​ 接口

/**
* @author BNTang
*/
public interface Printable {
void printString(String s);
}

方法引用符::: 参数传给了 System 当中

/**
* @author BNTang
*/
public class PrintableMain {
public static void main(String[] args) {
usePrintable(System.out::println);
}

private static void usePrintable(Printable printable) {
printable.printString("test");
}
}

方法引用符

​::​​ 该符号为引用运算符,而它所在的表达式被称为方法引用

推导与省略

  • 如果使用 Lambda,那么根据 “可推导就是可省略” 的原则,无需指定参数类型,也无需指定的重载形式,它们都将被自动推导
  • 如果使用方法引用,也是同样可以根据上下文进行推导
  • 方法引用是 Lambda 的孪生兄弟

引用类方法

引用类方法,其实就是引用类的静态方法,格式:​​类名::静态方法​​​,下面将给出一段示例进行参考,首先新建一个 ​​Converter​​ 接口

/**
* @author BNTang
*/
public interface Converter {

Number convert(String str);

}

然后 ​​psvm​​ 进行使用一下如下

/**
* @author BNTang
*/
public class ConverterMain {
public static void main(String[] args) {
useConverter((String str) -> {
return Integer.parseInt(str);
});
}

private static void useConverter(Converter converter) {
System.out.println(converter.convert("6666"));
}
}

如上的写法存在简化的写法,一步一步来进行改造,首先先来改造一下 Lambda 的简写写法,改造之后如下

/**
* @author BNTang
*/
public class ConverterMain {
public static void main(String[] args) {
useConverter(str -> Integer.parseInt(str));
}

private static void useConverter(Converter converter) {
System.out.println(converter.convert("6666"));
}
}

Lambda 表达式的改造完成了,那么就来开始看看引用类方法吧,进行改造如下, Lambda 表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数

/**
* @author BNTang
*/
public class ConverterMain {
public static void main(String[] args) {
useConverter(Integer::parseInt);
}

private static void useConverter(Converter converter) {
System.out.println(converter.convert("6666"));
}
}

引用对象方法

格式:​​对象::成员方法​​​ 不多说什么直接上案例了,自行参考,新建一个 ​​CalculateInterface​​ 接口

/**
* @author BNTang
*/
public interface CalculateInterface {
void calculate(Integer numOne, Integer numTwo);
}

然后在新建一个 ​​CalculateString​​ 普通的类

/**
* @author BNTang
*/
public class CalculateString {

public void printCalculate(Integer numOne, Integer numTwo) {
System.out.println(numOne + numTwo);
}

}

在进行 ​​psvm​​ 进行测试使用如下

/**
* @author BNTang
*/
public class CalculateString {

public void printCalculate(Integer numOne, Integer numTwo) {
System.out.println(numOne + numTwo);
}

}

我没有写的一步到位,主要是为了更好了让阅读者看到一步一步简化和演变的过程,进行改造 Lambda 的简写写法如下

/**
* @author BNTang
*/
public class CalculateMain {
public static void main(String[] args) {
useCalculate((a, b) -> System.out.println(a + b));
}

private static void useCalculate(CalculateInterface calculateInterface) {
calculateInterface.calculate(1, 2);
}
}

改造就到这,接下来开始就来看看对象方法的引用吧,首先我实例化了一个对象,然后在调用 ​​useCalculate​​ 里面就可以进行对象方法的引用了,Lambda 表达式被对象的实例方法替代的时候,它的形式参数全部传递给了该方法作为参数, 如下所示

/**
* @author BNTang
*/
public class CalculateMain {
public static void main(String[] args) {

CalculateString calculateString = new CalculateString();
useCalculate(calculateString::printCalculate);
}

private static void useCalculate(CalculateInterface calculateInterface) {
calculateInterface.calculate(1, 2);
}
}

引用类的实例方法

格式和上面的一样不在介绍,废话不多说直接上代码,新建一个 ​​MyString​​ 接口

/**
* @author BNTang
*/
public interface MyString {
String mySubString(String s, int x, int y);
}

老规矩,先来看看最初的 Lambda 写法

/**
* @author BNTang
*/
public class MyStringMain {
public static void main(String[] args) {
useMyString((String s, int x, int y) -> {
return s.substring(x, y);
});
}

private static void useMyString(MyString myString) {
System.out.println(myString.mySubString("HelloWorld", 2, 5));
}
}

Lambda 简化写法,至于简化的原理我之前的 Lambda 文章已经解释过了

/**
* @author BNTang
*/
public class MyStringMain {
public static void main(String[] args) {
useMyString((s, x, y) -> s.substring(x, y));
}

private static void useMyString(MyString myString) {
System.out.println(myString.mySubString("HelloWorld", 2, 5));
}
}

引用类的实例方法,Lambda 表达式被类的实例方法替代的时候,第一个参数作为调用者,后面的参数全部传递给了该方法作为参数,例如第一个参数就是我们上方写的 ​​HelloWorld​​ 它作为调用者,后面的参数全部传递给了该方法作为参数,改造之后的内容如下所示

/**
* @author BNTang
*/
public class MyStringMain {
public static void main(String[] args) {
useMyString(String::substring);
}

private static void useMyString(MyString myString) {
System.out.println(myString.mySubString("HelloWorld", 2, 5));
}
}

引用构造器

引用构造器,其实就是引用构造方法,废话不多说直接上代码,使用格式同上,新建一个 ​​Person​​ 类

/**
* @author BNTang
*/
public class Person {

private String name;
private int age;

public Person() {
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

在新建一个 ​​PersonBuildInterface​​ 接口

/**
* @author BNTang
*/
public interface PersonBuildInterface {
Person build(String name, int age);
}

​psvm​​ 进行测试如下,和之前一样的一步一步简化到最终的简化代码

/**
* @author BNTang
*/
public class PersonMain {
public static void main(String[] args) {
usePersonBuilder((name, age) -> {
return new Person(name, age);
});
}

private static void usePersonBuilder(PersonBuildInterface personBuildInterface) {
Person bnTangPerson = personBuildInterface.build("BNTang", 23);
System.out.println(bnTangPerson.getName() + "," + bnTangPerson.getAge());
}
}

简化 Lambda 写法

/**
* @author BNTang
*/
public class PersonMain {
public static void main(String[] args) {
usePersonBuilder((name, age) -> new Person(name, age));
}

private static void usePersonBuilder(PersonBuildInterface personBuildInterface) {
Person bnTangPerson = personBuildInterface.build("BNTang", 23);
System.out.println(bnTangPerson.getName() + "," + bnTangPerson.getAge());
}
}

改造引用构造器

/**
* @author BNTang
*/
public class PersonMain {
public static void main(String[] args) {
usePersonBuilder(Person::new);
}

private static void usePersonBuilder(PersonBuildInterface personBuildInterface) {
Person bnTangPerson = personBuildInterface.build("BNTang", 23);
System.out.println(bnTangPerson.getName() + "," + bnTangPerson.getAge());
}
}

使用说明:Lambda 表达式被构造器替代的时候,它的形式参数全部传递给了构造器作为参数

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 16天前 0

暂无评论

TEZNKK3IfmPf