Lambda表达式
来源:互联网 发布:淘宝推广返利网 编辑:程序博客网 时间:2024/06/16 11:56
最近在学习设计模式,star了iluwatar/java-design-patterns · GitHub这个项目。在读源代码的时候遇到了一些困惑,经过了解,原来是java8引入的新特性——lambda表达式。
先看看令我困惑的代码吧。
public static void main(String[] args) { WeaponFactory factory = WeaponFactory.factory(builder -> { builder.add(WeaponType.SWORD, Sword::new); builder.add(WeaponType.AXE, Axe::new); builder.add(WeaponType.SPEAR, Spear::new); builder.add(WeaponType.BOW, Bow::new); }); Weapon axe = factory.create(WeaponType.AXE); System.out.println(axe); }
嗯,就是这部分。
builder -> { builder.add(WeaponType.SWORD, Sword::new); builder.add(WeaponType.AXE, Axe::new); builder.add(WeaponType.SPEAR, Spear::new); builder.add(WeaponType.BOW, Bow::new); }
编译器告诉我builder是Builder接口的一个引用。Builder接口的代码如下。
public interface Builder { void add(WeaponType name, Supplier<Weapon> supplier); }
我们熟悉的写法。
public static void main(String[] args) { WeaponFactory factory = WeaponFactory.factory(new Consumer<Builder>() { @Override public void accept(Builder t) { t.add(WeaponType.SWORD,Sword::new); t.add(WeaponType.SPEAR, SPEAR::new); t.add(WeaponType.AXE, new Supplier<Weapon>() { @Override public Weapon get() { return new AXE(); } }); } }); Weapon axe = factory.create(WeaponType.AXE); System.out.println(axe); }
什么是lambda表达式
lambda表达式用于代替匿名内部类。以前,为了实现带一个方法的接口,往往会定义一个匿名类并复写接口方法,代码显得很臃肿。比如我们经常这样写:
Runnable Runnable = new Runnable() { @Override public void run() { System.out.println("Hello World!"); } };
但现在可以这样:
Runnable Runnable = ()->{ System.out.println("Hello World!"); }
lambda表达式的使用
lambda表达式针对的对象是“函数接口(functional interface)”,这是Java8新引入的概念。它的定义是:一个接口,如果只有一个显式声明的抽象方法,那么它就是一个函数接口。
对上面这段话的一种典型的理解方式是:lambda表达式针对的对象,只包含一个方法的接口(这个是规则),你可以自定义任何接口,只要包含一个方法就可以。
另外,在生成文档注释方面,Java8提供了一个@FunctionalInterface注释,来标记这样的接口。
然而请注意:只有一个显示声明的抽象方法,所以函数接口中可以有其他的方法。例如我们经常使用的Comparator接口:
@FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); }
它里面声明了两个方法,貌似不符合函数接口的定义,但它的确是函数接口。这是因为equals方法是Object的,所有的接口都会声明Object的public方法——虽然大多是隐式的。所以,Comparator显式的声明了equals不影响它依然是个函数接口。
同时,我们产生了新的问题,当目标函数有一个或多个参数并且有返回值呢?因为我们之前的例子里都没有参数,巧妙的避开了这个问题。那现在应该如何使用lambda表达式呢?依旧很简单。
Comparator<String> comparator =(String s1,String s2)->{ return s1.toLowerCase().compareTo(s2.toLowerCase()); };
甚至,参数类型也可以省略,Java编译器会根据上下文推断出来:
Comparator<String> comparator =(s1,s2)->{ return s1.toLowerCase().compareTo(s2.toLowerCase()); };
- Lambda Expressions(Lambda表达式)
- Lambda表达式
- Lambda表达式
- Lambda 表达式
- Lambda表达式
- lambda表达式
- lambda表达式
- Lambda表达式
- Lambda表达式
- Lambda表达式
- Lambda表达式
- Lambda 表达式
- Lambda表达式
- Lambda 表达式
- Lambda 表达式
- Lambda表达式
- Lambda表达式
- Lambda 表达式
- 2016-10-05
- JAVA从菜鸟【入门】到新手【实习】一一每日三读,视野领域的拓展,心理调节
- 排序总结系列五:快速排序
- 如何搭建SSM(SpringMvc+mybatis+Spring)java web工程
- WEB应用防火墙与数据库应用防火墙有什么区别
- Lambda表达式
- 侩子手
- npm安装cordova时警告:npm WARN deprecated minimatch@2.0.10: Please update to minimatch 3.0.2 or higher to
- 最长公共字串与最长公共子序列
- 排序总结系列六:归并排序
- C/C++/Java 中static对比
- Java NIO系列教程(二) Channel
- 并查集的例题
- 多线程学习总结(六)——实现多线程的方法之Fork/Join