java数组构造方法怎么调用_02-方法引用、构造器引用、数组引用

通过 lambda 表达式,我们可以更加优雅的替代匿名内部类,生成一个函数式接口的实例,使我们的编码更加简洁。

这篇文章进一步介绍Java8的新特性,可以让我们的编码相对于 lambda 表达式更为简洁。

分别是:方法引用、构造器引用还有数组引用。

说白了就是借用别人的轮子。

提示:

这篇文章结合函数式接口和lambda表达式进行讲解,Demo中应用了一些Java内置的函数式接口,比如 BiConsumer、BinaryOperator、BiFunction等等。

还不熟悉这个这两个特性,或者对一些Java内置的函数式接口不熟悉的,请看先阅读 01-函数式接口和 lambda 表达式。

若想了解java8其它新特性,请到 00-java8常用新特性文章索引 阅读。

1 方法引用

1.1 方法引用是什么

如果已经有其他类的某一个方法实现了 函数式接口抽象方法需要实现的代码逻辑(lambda 体),可以通过方法引用,直接引用该类已经实现的方法。

简单地讲,只要满足以下条件,即可使用方法引用:

参数列表一样

返回值一样

lambda体的代码逻辑和目标类成员方法的代码逻辑一样

1.2 方法引用的格式

使用**::**(双冒号)将类名或者对象名和方法名分隔开。

对象::实例方法名

类名::实例方法名

类名::静态方法名

1.3 方法引用怎么用

1.3.1 对象::实例方法名

对象::实例方法名 Demo

/**

* Description: 运算类

*

* @author Xander

* datetime: 2020/9/1 0:14

*/

public class Calc {

/**

* 加法运算,对象::实例方法名 时可以使用

*

* @param x

* @param y

* @return

*/

public int add(int x, int y) {

return x + y;

}

/**

* 乘法运算,类名::静态方法名 时可以使用

*

* @param x

* @param y

* @return

*/

public static long multi(long x, long y) {

return x * y;

}

}

/**

* Description: 方法引用简单应用

*

* @author Xander

* datetime: 2020/8/31 23:57

*/

public class MethodRefTest {

@Test

public void test00() {

//lambda表达式

Consumer cLambda = str -> System.out.println(str);

// 对象::实例方法名

Consumer cMethRef = System.out::println;

cLambda.accept("hello Lambda");

cMethRef.accept("hello Method Reference");

}

@Test

public void test01() {

Calc calc = new Calc();

//lambda表达式

BinaryOperator oprLambda = (x, y) -> x + y;

// 对象::实例方法名

BinaryOperator oprMethRef = calc::add;

System.out.println(oprLambda.apply(2, 3));

System.out.println(oprMethRef.apply(2, 3));

}

}

test00、test01两个测试用例运行结果:

hello Method Reference

hello Method Reference

5

5

1.3.2 类名::实例方法名

类名::实例方法名,这个使用的场景比较特殊,要求第一个参数是实例方法的调用者,剩余的参数都是实例方法的入参,剩余的参数个数可以是0个或者多个。

提示:目标类的实例方法的参数列表会比函数式接口的抽象方法入参个数少一个,因为第一个参数是实例方法的调用者。

public class Person {

//姓名

private String name;

//年龄

private long age;

public Person(String name, long age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public long getAge() {

return age;

}

public void setAge(long age) {

this.age = age;

}

@Override

public String toString() {

return "Person{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

/**

* 打招呼

*

* @param p

*/

public void sayHello(Person p) {

System.out.println(this.getName() + " say hello to " + p.getName());

}

}

public class MethodRefTest {

...

@Test

public void test02() {

//lambda表达式

BiConsumer bcLambda = (x, y) -> System.out.println(x.getName()+" say hello to "+y.getName());

// 类名::实例方法名

BiConsumer bcMethRef = Person::sayHello;

bcLambda.accept(new Person("P1",18),new Person("P2",18));

bcMethRef.accept(new Person("P3",18),new Person("P4",18));

}

@Test

public void test03() {

// 判断两个String是否equals

//lambda表达式

BiFunction bfLambda = (x, y) -> x.equals(y);

// 类名::实例方法名

BiFunction bfMethRef = String::equals;

System.out.println(bfLambda.apply("a", "b"));

System.out.println(bfMethRef.apply("a", "a"));

//求 String 的 hashCode

//lambda表达式

Function funcLambda = str -> str.hashCode();

// 类名::实例方法名

Function funcMethRef = String::hashCode;

System.out.println(funcLambda.apply("a"));

System.out.println(funcMethRef.apply("a"));

}

}

test02、test03 运行结果:

P1 say hello to P2

P3 say hello to P4

false

true

97

97

1.3.3 类名::实例方法名

@Test

public void test04() {

//lambda表达式

BinaryOperator bfLambda = (x, y) -> x * y;

// 类名::静态方法名

BinaryOperator bfMethRef = Calc::multi;

System.out.println(bfLambda.apply(2L, 3L));

System.out.println(bfMethRef.apply(2L, 3L));

}

@Test

public void test05() {

//lambda表达式

BinaryOperator bfLambda = (x, y) -> Math.pow(x,y);

// 类名::静态方法名

BinaryOperator bfMethRef = Math::pow;

System.out.println(bfLambda.apply(2D, 3D));

System.out.println(bfMethRef.apply(2D, 3D));

}

test04、test05 运行结果:

6

6

8.0

8.0

2 构造器引用

2.1 构造器引用是什么

构造器引用依然是要结合函数式接口进行使用。

为了简化函数式接口的抽象方法需要实现的代码逻辑(lambda 体),如果lambda体中有返回值,而且返回值类型的构造器参数列表和函数式接口抽象方法的参数列表一致。

这时,就可以使用构造器引用。

看定义,应该看得很懵逼,直接看下面的demo。

2.2 语法格式

类名::new

2.3 构造器引用简单使用

@Test

public void test06() {

//通过函数式接口IntFunction 创建 Integer 实例

//lambda表达式

IntFunction intFuncLambda = i -> new Integer(i);

// 构造器引用:类名::new

IntFunction intFuncConstRef = Integer::new;

//lambda表达式生成 函数式接口IntFunction 的实例,执行apply方法后,生成的 Integer 实例

Integer integerLambda = intFuncLambda.apply(5);

//构造器引用生成 函数式接口IntFunction 的实例,执行apply方法后,生成的 Integer 实例

Integer integerConstRef = intFuncConstRef.apply(15);

System.out.println(integerLambda.intValue());

System.out.println(integerConstRef.intValue());

}

@Test

public void test07() {

//通过函数式接口BiFunction 创建 Person 实例

//lambda表达式

BiFunction bfLambda = (name, age) -> new Person(name, age);

// 构造器引用:类名::new

BiFunction bfConstRef = Person::new;

// lambda表达式生成的Person

Person personLambda = bfLambda.apply("张三", 20L);

// 构造器引用生成的Person

Person personConstRef = bfConstRef.apply("李四", 25L);

System.out.println(personLambda);

System.out.println(personConstRef);

}

运行结果:

5

15

Person{name='张三', age=20}

Person{name='李四', age=25}

3 数组引用

3.1 是什么

如果你理解了上面的构造器引用,那理解数组引用的使用就很简单了。

构造器引用通过函数式接口的抽象方法调用,使用返回值类型中与函数式接口抽象方法的参数列表一致的构造器,创建一个对象。

数组引用:通过函数式接口的抽象方法调用,将参数作为返回值数组的构造器入参,创建一个数组。

单看这句话应该还是懵逼,下面看一下使用demo。

3.2 语法格式

类名[]:new

3.3 数组引用简单应用

@Test

public void test08() {

// 通过数组引用,生成 String[] 实例

//lambda表达式

Function funcLambda = length -> new String[length];

// 数组引用:类名[]::new

Function funcArrayRef = String[]::new;

// lambda表达式生成的String[]

String[] arrayLambda = funcLambda.apply(2);

arrayLambda[0] = "lambda";

// 数组引用生成的String[]

String[] arrayArrayRef = funcArrayRef.apply(2);

arrayArrayRef[0] = "Array Reference";

System.out.println("lambda生成数组:" + Arrays.toString(arrayLambda));

System.out.println("数组引用生成数组:" + Arrays.toString(arrayArrayRef));

}

运行结果:

lambda生成数组:[lambda, null]

数组引用生成数组:[Array Reference, null]

方法引用,构造器引用,数组引用都需要结合函数式接口进行使用,当执行函数式接口的抽象方法时,其实调用的是引用类的方法逻辑或者构造器的逻辑,这就是典型的借轮子。

使用简单,设计灵巧,但要达到熟练程度,还需要多加理解,学以致用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值