栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

引用Java8中具有不同参数的方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

引用Java8中具有不同参数的方法

从Oracle方法参考教程:

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

以下是对特定类型的任意对象的实例方法的引用示例:

String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia","Robert", "Michael", "Linda" };

Arrays.sort(stringArray, String::compareToIgnoreCase);

方法参考的等效lambda表达式

String::compareToIgnoreCase
将具有形式参数列表
(String a, Stringb)
,其中a和b是用于更好地描述此示例的任意名称。该方法引用将调用该方法
a.compareToIgnoreCase(b)

但是,

::
操作员的真正含义是什么?好吧,
::
运营商可以这样描述(从这个SO问题):

可以以不同的样式获得方法参考,但是它们的含义相同:

  1. 静态方法(
    ClassName::methodName
  2. 特定对象的实例方法(
    instanceRef::methodName
  3. 特定对象的超级方法(
    super::methodName
  4. 特定类型(
    ClassName::methodName
    )的任意对象的实例方法
  5. 类构造函数参考(
    ClassName::new
  6. 数组构造函数参考(
    TypeName[]::new


因此,这意味着该方法引用

String::compareToIgnoreCase
属于第二类(
instanceRef::methodName
),这意味着它可以转换为
(a,b) -> a.compareToIgnoreCase(b)

我相信以下示例进一步说明了这一点。甲

Comparator<String>
包含运行在两个一种方法
String
的操作数并返回
int
。可以将其伪描述为
(a,b) ==> return int
(其中操作数为
a
b
)。如果您以这种方式查看,则以下所有内容都属于该类别:

// Trad anonymous inner class// Operands: o1 and o2. Return value: intComparator<String> cTrad = new Comparator<String>() {    @Override    public int compare(final String o1, final String o2) {        return o1.compareToIgnoreCase(o2);    }};// Lambda-style// Operands: o1 and o2. Return value: intComparator<String> cLambda = (o1, o2) -> o1.compareToIgnoreCase(o2);// Method-reference à la bullet #2 above. // The invokation can be translated to the two operands and the return value of type int. // The first operand is the string instance, the second operand is the method-parameter to// to the method compareToIgnoreCase and the return value is obviously an int. This means that it// can be translated to "instanceRef::methodName".Comparator<String> cMethodRef = String::compareToIgnoreCase;

这个很棒的SO-
answer解释了lambda函数是如何编译的
。Jarandinor在那个答案中引用了Brian
Goetz优秀文档中的以下段落,该段落更多地描述了lambda翻译。

我们没有描述生成用于实现lambda表达式的对象的字节码(例如,调用内部类的构造函数),而是描述了构造lambda的方法,并将实际构造委托给语言运行时。该配方被编码在invokedynamic指令的静态和动态参数列表中。

基本上,这意味着本地运行时决定如何转换lambda。

Brian继续说:

方法引用与lambda表达式的处理方式相同,不同之处在于,大多数方法引用不需要分解为新方法;我们可以简单地为引用的方法加载一个常量方法句柄,并将其传递给元工厂。

所以,lambda表达式被 到一个 新的方法 。例如

class A {    public void foo() {        List<String> list = ...        list.forEach( s -> { System.out.println(s); } );    }}

上面的代码将 简化 为以下形式:

class A {    public void foo() {        List<String> list = ...        list.forEach( [lambda for lambda$1 as Consumer] );    }    static void lambda$1(String s) {        System.out.println(s);    }}

但是,Brian也在文档中对此进行了解释:

如果desugared方法是实例方法,则将接收方视为第一个参数

Brian继续解释说 ,lambda剩余的参数作为参数传递给所引用的方法

因此,借助Moandji Ezana的此项,可以将

compareToIgnoreCase
as 的废除
Comparator<String>
分解为以下步骤:

  • Collections#sort
    对于一个
    List<String>
    期望
    Comparator<String>
  • Comparator<String>
    是方法的功能接口,
    int sort(String, String)
    相当于
    BiFunction<String, String, Integer>
  • 因此,比较器实例可以由
    BiFunction
    -compatible lambda提供:
    (String a, String b) -> a.compareToIgnoreCase(b)
  • String::compareToIgnoreCase
    引用带有
    String
    参数的实例方法,因此它与上述lambda兼容:
    String a
    成为接收方并
    String b
    成为方法参数

编辑: 从OP输入后,我添加了一个 低级 示例,说明了 废止



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/498140.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号