jdk8之lambda

原创
2014/01/27 14:16
阅读数 2.4K

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());
	}
}
  • 收工。
展开阅读全文
加载中
点击加入讨论🔥(1) 发布并加入讨论🔥
1 评论
9 收藏
0
分享
返回顶部
顶部