2019独角兽企业重金招聘Python工程师标准>>>
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;}@Overridepublic 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());}
}
- 收工。