[Java]lambda表达式
1.lambda表达式的使用目的
.用于解决内部类使用时的冗余和不便,提供更简洁的语法
2.lambda表达式的适用场景
现有的类库大量使用了函数式接口,通过沿用这种模式,我们使得现有类库能够直接使用lambda表达式。例如下面是Java SE 7中已经存在的函数式接口:
- java.lang.Runnable
- java.util.concurrent.Callable
- java.security.PrivilegedAction
- java.util.Comparator
- java.io.FileFilter
- java.beans.PropertyChangeListener
除此之外,Java SE 8中增加了一个新的包:java.util.function
,它里面包含了常用的函数式接口,例如:
Predicate<T>
——接收T
对象并返回boolean
Consumer<T>
——接收T
对象,不返回值Function<T, R>
——接收T
对象,返回R
对象Supplier<T>
——提供T
对象(例如工厂),不接收值UnaryOperator<T>
——接收T
对象,返回T
对象BinaryOperator<T>
——接收两个T
对象,返回T
对象
除了上面的这些基本的函数式接口,我们还提供了一些针对原始类型(Primitive type)的特化(Specialization)函数式接口,例如IntSupplier
和LongBinaryOperator
。(我们只为int
、long
和double
提供了特化函数式接口,如果需要使用其它原始类型则需要进行类型转换)同样的我们也提供了一些针对多个参数的函数式接口,例如BiFunction<T, U, R>
,它接收T
对象和U
对象,返回R
对象。
3.lambda表达式的注意事项
编译器会检查lambda表达式的类型和目标类型的方法签名(method signature)是否一致。当且仅当下面所有条件均满足时,lambda表达式才可以被赋给目标类型T
:
T
是一个函数式接口- lambda表达式的参数和
T
的方法参数在数量和类型上一一对应 - lambda表达式的返回值和
T
的方法返回值相兼容(Compatible) - lambda表达式内所抛出的异常和
T
的方法throws
类型相兼容
lambda表达式对 值 封闭,对 变量 开放
int sum = 0; list.forEach(e -> { sum += e.size(); }); // Illegal, close over values List<Integer> aList = new List<>(); list.forEach(e -> { aList.add(e); }); // Legal, open over variables
4.lambda表达式的使用示例
.Runnable
package com.xdsux.java.thread; public class BasicThreads { public BasicThreads() { // TODO Auto-generated constructor stub } public static void main(String[] args) { //普通写法 for (int i = 5; i > 0; i--) { Thread t = new Thread (new LiftOff()); t.start(); System.out.println("Waiting for LiftOff"); } //lambda表达式 for (int i = 5; i > 0; i--) { Thread t = new Thread(() -> System.out.println("lambda1.")); t.start(); } } }
.ActionListener
package com.xdsux.java.lambda; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; public class Main extends JFrame { private JButton jb; public Main() { this.setBounds(200, 400, 400, 200); this.setTitle("TestLanmda"); jb = new JButton("click"); //lambda //jb.addActionListener(event -> System.out.println("click")); jb.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { getClick(); } }); this.add(jb); this.setVisible(true); this.setDefaultCloseOperation(EXIT_ON_CLOSE); } public void getClick() { System.out.println("click1"); } public static void main(String[] args) { new Main(); } }
.集合和Stream
package com.xdsux.java.lambda; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class lambdaTest { public static void main(String[] args) { // TODO Auto-generated method stub List<String> ls = new ArrayList<>(); ls.add("s1"); ls.add("s2"); Stream<String> s = ls.stream().map(p -> p.concat("lanbda3")); System.out.println(s.collect(Collectors.toList())); } }