最近在学习jdk8新API,jdk8在比较器Comparator接口里新添了大量的default方法和static方法供我们使用,我们可以直接使用这些默认已经实现好的比较器配合使用Lambda表达式来进行比较排序。但Comparator接口是个泛型类,其中的接口都跟泛型有关,所以在使用的时候还是会出现一些跟泛型类型参数有关的问题。

看我的测试用例:

Listlist = Arrays.asList("nihao", "hello", "world", "welcome");

//按字符串长度排序

Collections.sort(list, (item1, item2) -> item1.length() - item2.length() );

list.forEach(System.out::println);

程序正确运行。再看下面的代码:

好,代码编译出错,idea给我们提示,无法解析length()这个方法。意思是,java编译器无法从参数item中获取length()这个方法信息。原因只有一个,形参item不是String类型的。那我们看看此时item被编译器解析成的类型变量是:

java编译器此时把item当作Object类型,所以找不到length()方法。他推断出的类型并不是我们想要的类型(就是说此时java编译器无法准确去推断出我们lambda表达式里的参数类型),那么我们可以显式地给参数声明它的类型。

改进代码:

这样就可以编译通过了。但是我在想为什么java编译器把item当作Object类型呢?其实java编译器推断目标类型跟泛型有关( Java 8 新特性:泛型目标类型推断),来我们看看这个方法的泛型参数:

泛型 < ? super T > 的意思是接受的类型参数是T或者T的父类,对List进行排序,编译器可以推断出T为String类型,那么comparingInt(ToIntFunction < ? super T > keyExtractor)在上面的代码中就是接受类型参数为String类型,或者String的更上一级类型。所以java编译器不确定你到底是传什么类型的参数,那么它只能直接推断成最顶级的类型,即Object类型。以保证向下兼容。所以为了更准确的使用lambda参数,我们这里要显式写明参数类型String item。其实我们可以验证一下,刚才说了,这里只接受String或String的更高一级类型。看代码:

在这里我显式地定义成Boolean类型的参数item,idea编译报错。因为Stirng的上限为Object没有Boolean类型。好再改一下代码:

没有报错。那么按照之前的推断,Serializable应该是String之上的类型。

String实现了这些接口,符合泛型 < ? super T > 的定义。

这就是我对这个编译器类型推断的问题分析的整个思考过程。本来自圆其说,以为问题解决了。后来,我看到demo中的第一行代码:

Collections.sort(list, (item1, item2) -> item1.length() - item2.length() );

这里java编译器可以推断出lambda表达式里的参数类型,但是你一看API

我蒙蔽了。。。怎么回事,想了半天,这里怎么解释?还是泛型< ? super T >为什么这里他可以推断出item1,item2是String类型呢?

java item 类型参数_Java8中对Lambda表达式中方法参数的类型推断(一)相关推荐

  1. java:java8新特性(Lambda 表达式、方法引用、构造器引用、数组引用、Stream API)

    速度更快 对 HashMap .ConcurrentHashMap低层的数据结构(数组+链表+二叉树) 低层的内存结构(将永久区更新为元空间,元空间使用的是物理内存) 代码更少(增加了新的语法 Lam ...

  2. lambda 表达式中的 this 与普通情况下的 this 指向

    lambda 表达式中的 this 与普通情况下的 this 指向 Java JavaScript this 绑定 总结与提醒   很多编程语言都支持 lambda 表达式,不过对于不同编程语言,其 ...

  3. 如何在Java中使用Lambda表达式

    如何在Java中使用Lambda表达式 Lambda表达式是Java 8新增的一个非常强大的特性.它使得函数式编程在Java中变得更加容易和直观. Lambda表达式的基础知识 在Java中,Lamb ...

  4. java lamdba表达式效率_java8新特性Lambda表达式为什么运行效率低

    Lambda表达式为什么运行效率低 准备 我为什么说Lambda表达式运行效率低. 先准备一个list: 先用Lambda表达式的方式来循环一下这个list: 运行时间大概为110ms 再用普通方式来 ...

  5. 探索Java语言与JVM中的Lambda表达式

    2019独角兽企业重金招聘Python工程师标准>>> 转载来源:http://www.admin10000.com/document/1291.html Lambda表达式是自Ja ...

  6. java8的表达式_java8中的Lambda表达式

    lambad表达式是一个匿名函数,既没有函数名的函数.在lambda表达式出现之前,java中更多使用的是匿名内部类所以有些刚刚接触lambda表达式的人会把lambda表达式误认为就是匿名内部类的简 ...

  7. mvc html.displayfor,我想了解@ Html.DisplayFor(modelItem = item.FirstName)中的lambda表达式...

    为了理解Visual Studio生成的代码,我也付出了很多努力. 除了提供有关lambda表达式的一般说明外,我想使用ASP.NET MVC框架作为上下文. 假设我们准备了一个具有2个属性的Mode ...

  8. java 8 lambda表达式中的异常处理

    文章目录 简介 处理Unchecked Exception 处理checked Exception 总结 java 8 lambda表达式中的异常处理 简介 java 8中引入了lambda表达式,l ...

  9. java lambda 表达式中的双冒号和箭头的用法 ::

    先构造一些数据,创建一个User类 java lambda 表达式中的双冒号的用法 :: 双冒号运算就是Java中的[方法引用],[方法引用]的格式是 类名::方法名 如下图所示 User是一个类, ...

  10. Java 8:在新的Nashorn JS引擎中编译Lambda表达式

    在最近的一篇文章中,我了解了Java 8和Scala如何实现Lambda表达式. 众所周知,Java 8不仅引入了对Javac编译器的改进,而且还引入了全新的解决方案-Nashorn. 这个新引擎旨在 ...

最新文章

  1. python yield用法_Python中迭代器和生成器的区别?
  2. 数智化转型人才“大考”,综合人才成为企业“基础设施”
  3. HashMap以及ConcurrentHashMap(volatile)
  4. js+jquery手写弹出提示框
  5. 深入了解帆软报表系统的启动过程二
  6. sqlalchemy用in_ 批量delete
  7. php实现事件监听与触发的方法
  8. 2021年危险化学品经营单位主要负责人考试报名及危险化学品经营单位主要负责人新版试题
  9. 监控软件加入智能零售 试着用人脸辨识让消费力提升
  10. DELL EMC Isilon配额Quota
  11. 大龄程序员的4年生涯
  12. 如何查看电子元器件的丝印信息
  13. 做自己想做的工作,你也可以
  14. 微信小程序 java校友录交流系统springboot
  15. 手撕七大排序 (二)
  16. 关于VS项目平台的x86,x64,Any CPU以及Debug和Release的区别
  17. Ubuntu下源码编译VirtualBox六 —— 源码编译(5)
  18. 多媒体个人计算机软件系统由,多媒体计算机软件系统由什么组成
  19. 招聘 | 多家区块链项目招募开发者
  20. oracle如何查询授权,oracle授权查询

热门文章

  1. Centos开机自动执行shell脚本启动tomcat服务器
  2. UIImageView只显示一半
  3. 微信原生支付 Native扫码支付( V3.3.7 版本)
  4. adb shell 出现 error :
  5. 网页素材精品:一组五彩缤纷的免费矢量背景素材
  6. Linux笔记1 修改主机名、ip以及指DNS
  7. 深入了解TMG企業版的獨立陣列
  8. 图纸管理软件_企业图纸文档的安全管理与使用,是否遇到这些图纸管理问题?...
  9. linux6.5输错密码锁定,干货分享:解决redhat6.5登陆后跳回Login,循环登陆问题
  10. 通过bocker把项目部署到容器后,也启动了镜像,但是浏览器报错网址连接不安全,建立安全连接失败,SSL接收到了一个超出最大准许长度的记录