首页 > 编程知识 正文

java8中双冒号如何传递参数,java8的双冒号怎样使用的

时间:2023-05-05 00:49:06 阅读:285590 作者:2667

java 8 双冒号操作

本文我们讨论java 8 中的双冒号(::)操作以及其使用场景。

从lambda表达式到双冒号(::)操作

我们知道使用lambda表达式可以让代码非常简洁。举例,创建比较器,使用下面语法:

Comparator c = (Computer c1, Computer c2) -> c1.getAge().compareTo(c2.getAge());

使用类型推断,可以简写为:

Comparator c = (c1, c2) -> c1.getAge().compareTo(c2.getAge());

为了使上面代码更可读,我们使用下面语法:

Comparator c = Comparator.comparing(Computer::getAge);

我们使用::操作简化lambda表达式调用特定方法,让我们的代码更有表现力。

了解原理

简单地说,当我们使用方法引用时,目标引用在::之前,方法名称在其值后,举例:

Computer::getAge;

上面方法引用标识调用Computer类的getAge方法。也可以Function一起使用:

Function getAge = Computer::getAge;

Integer computerAge = getAge.apply(c1);

我们使用函数引用,然后给其正确的参数执行。

方法引用

我们可以在多个地方使用::操作符。

静态方法

下面示例调用静态工具方法:

List inventory = Arrays.asList(

new Computer( 2015, "white", 35), new Computer(2009, "black", 65));

inventory.forEach(ComputerUtils::repair);

现有对象的实例方法

下面看有趣的应用场景——调用现有实例对象方法。我们使用System.out变量——PrintStream类型对象,有print方法:

Computer c1 = new Computer(2015, "white");

Computer c2 = new Computer(2009, "black");

Computer c3 = new Computer(2014, "black");

Arrays.asList(c1, c2, c3).forEach(System.out::print);

特定类型的任意对象的实例方法

Computer c1 = new Computer(2015, "white", 100);

Computer c2 = new MacbookPro(2009, "black", 100);

List inventory = Arrays.asList(c1, c2);

inventory.forEach(Computer::turnOnPc);

上面代码没有在特定实例引用turnOnPc方法,而是在类自身。第四行代码将在inventory中每个实例上调用turnOnPc方法。也就是说——调用Computer实例c1的turnOnPc方法,然后调用Computer实例c2的turnOnPc方法.

特定对象超类方法

假设在Computer超类中有下面方法:

public Double calculateValue(Double initialValue) {

return initialValue/1.50;

}

MacbookPro 子类定义方法:

@Override

public Double calculateValue(Double initialValue){

Function function = super::calculateValue;

Double pcValue = function.apply(initialValue);

return pcValue + (initialValue/10) ;

}

在MacbookPro 实例上调用calculateValue方法:

macbookPro.calculateValue(999.99);

也产生对Computer父类的calculateValue方法的调用。

构造器应用

创建新的实例

引用构造器实例化对象可以简化为:

@FunctionalInterface

public interface InterfaceComputer {

Computer create();

}

InterfaceComputer c = Computer::new;

Computer computer = c.create();

如何构造器有两个参数:

BiFunction c4Function = Computer::new;

Computer c4 = c4Function.apply(2013, "white");

如果有三个或更多参数,需要定义新的函数接口:

@FunctionalInterface

interface TriFunction {

R apply(A a, B b, C c);

default TriFunction andThen( Function super R, ? extends V> after) {

Objects.requireNonNull(after);

return (A a, B b, C c) -> after.apply(apply(a, b, c));

}

}

初始化对象代码:

TriFunction c6Function = Computer::new;

Computer c3 = c6Function.apply(2008, "black", 90);

创建数组

最后,我们看看如何创建5个Computer对象数组:

Function computerCreator = Computer[]::new;

Computer[] computerArray = computerCreator.apply(5);

总结

java8 引入双冒号操作,在一些场景中非常有用,特别在stream的连接操作中。通过理解函数式接口可以更好地理解其原理。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。