Oracle号称今年一定发布jdk8, 即使有bug, jdk8无疑最大的宠儿就是lambda表达式了,还是直接上代码,看看lambda表达式怎么了。
- 环境:
openjdk8, eclipse4.3.1(支持jdk8编译)
- 实例代码:
// Demo1
public class RunnableTest {
public static void main(String[] args) {
Runnable runner = () -> System.out.println("I am lambda runner.");
runner.run();
}
}
// Demo2
import javax.swing.JButton;
public class ListenerTest {
public static void main(String[] args) {
JButton btn = new JButton();
btn.addActionListener(
e -> System.out.println("Event Source is: " + e.getSource())
);
}
}
// Demo3
//Student.java
public class Student {
private String name;
private float score;
public Student(String name, float score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getScore() {
return score;
}
public void setScore(float score) {
this.score = score;
}
@Override
public String toString() {
return "Student [name=" + name + ", score=" + score + "]";
}
}
// ComparatorTest.java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class ComparatorTest {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
Random r = new Random();
for (int i=0; i<5; i++){
students.add(new Student("stu"+i, r.nextFloat() * 100));
}
Collections.sort(students,
(Student s1, Student s2) -> (int)(s1.getScore() - s2.getScore())
);
for (Student s: students){
System.out.println(s);
}
}
}
看了这3个例子,就会觉得lambda很偏向于函数式编程(如Lisp这种语言),这种语言很简洁,但是易读性不是那么好,没办法,又想简洁又想易读式不太容易的,以前java有匿名类,我们通常就实现这个匿名类里的一个接口,这叫Function Interface,现在我们就可以不用写这个匿名类了,就直接实现接口就行了,就像上面的Demo一样。
下面说一下lambda在Collection上的工作:
- Function接口:
public interface Function<T, R> {
R apply(T t);
...
}
Function接受一种类型T输入,以另一类型R输出, 看实例:
import java.util.function.Function;
public class Person {
private String firstName;
private String lastName;
private int age;
public Person(String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/**
* 这里就用Function实现可订制的信息输出
* Function: 将输入类型转换为输出类型,这里即将Person输入,以String输出
*/
public String printCustom(Function<Person, String> f){
return f.apply(this);
}
}
测试用例:
import java.util.function.Function;
/**
* Function 测试
*/
public class FunctionTest {
public static void main(String[] args) {
Person person = new Person("Hello", "Function");
// 用lambda表达式作为参数传递
System.out.println(
person.printCustom(p -> "FirstName : " + p.getFirstName())
);
// 用lambda表达式构建Function对象
Function<Person, String> westernStyle = p -> {
return "LastName: " + p.getLastName() + ", FirstName: " + p.getFirstName();
};
Function<Person, String> eastStyle = p -> {
return "FirstName: " + p.getFirstName() + ", LastName: " + p.getLastName();
};
System.out.println(person.printCustom(westernStyle));
System.out.println(person.printCustom(eastStyle));
}
}
输出结果:
- 集合的迭代:
import java.util.ArrayList;
import java.util.List;
/**
* 通过lambda迭代集合
*/
public class LoopTest {
public static void main(String[] args) {
List<Person> ps = new ArrayList<>();
for (int i=0; i<5; i++){
ps.add(new Person("XX"+i, "OO"+i));
}
ps.forEach(
p -> System.out.println(p.getFirstName())
);
//ps.forEach(Person::printEast);
System.out.println("-------------------------");
ps.forEach(
p -> {
System.out.println(
p.printCustom(
r->r.getLastName()+" " + r.getFirstName()
)
);
}
);
}
}
- Predicate接口,它接受一种输入类型,并通过test接口方法返回boolean值:
public interface Predicate<T> {
boolean test(T t);
...
}
Predicate可以有效实现集合过滤操作:
测试用例:
/**
* Predicate实现集合过滤
*/
public class PredicateTest {
public static void main(String[] args) {
List<Person> ps = new ArrayList<>();
Random r = new Random();
for (int i=0; i<10; i++){
ps.add(new Person("firstName"+i, "lastName"+i, r.nextInt(20) + 1));
}
Predicate<Person> children = p -> p.getAge() < 12;
Predicate<Person> teenagers = p -> p.getAge() >= 12 && p.getAge() < 18;
Predicate<Person> adults = p -> p.getAge() >= 18;
for (Person p : ps){
System.out.print(p.getFirstName() + "'s age is " + p.getAge());
if (children.test(p)){
System.out.println(", is a child.");
} else if (teenagers.test(p)){
System.out.println(", is a teenager.");
} else if(adults.test(p)){
System.out.println(", is an adult.");
}
}
}
}
输出结果:
- 2个综合些的例子:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class CollectTest {
public static void main(String[] args) {
List<Person> ps = new ArrayList<>();
Random r = new Random();
for (int i=0; i<10;i++){
ps.add(new Person("firstname"+i, "lastname"+i, r.nextInt(30) + 1));
}
// 过滤条件>18岁
Predicate<Person> adults = p -> p.getAge() > 18;
// 通过collect获取过滤后的集合
List<Person> filteredPersons = ps.stream().filter(adults).collect(Collectors.toList());
filteredPersons.forEach(
p -> System.out.println(p.getFirstName() + " "+ p.getLastName()+"'s age: " + p.getAge())
);
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.Random;
import java.util.function.Predicate;
/**
* 通过map来实现求最大值,平均值
*/
public class MapTest {
public static void main(String[] args) {
List<Person> ps = new ArrayList<>();
Random r = new Random();
for (int i=0; i<10;i++){
ps.add(new Person("firstname"+i, "lastname"+i, r.nextInt(30) + 1));
}
// 过滤条件>18岁
Predicate<Person> adults = p -> p.getAge() > 18;
//最大年龄
OptionalInt maxAge = ps.parallelStream().filter(adults)
.mapToInt(p -> p.getAge()).max();
System.out.println("最大年龄:" + maxAge.getAsInt());
// 求18岁以上的平均值
OptionalDouble average =
ps.parallelStream().filter(adults)
.mapToDouble(p -> p.getAge()).average();
System.out.println("平均年龄:" + average.getAsDouble());
}
}
- 收工。