Java8函数式编程

一,接口的默认方法
java8通过使用default关键字向接口添加非抽象方法实现,此功能也称为虚拟扩展方法。

二,Lambda表达式
1,函数式接口
指仅包含一个抽象方法,但可以有多个非抽象方法(默认方法)的接口。
Lamda表达式:匿名函数,一段可以传递的代码。
可以使代码量减少:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

import org.junit.Test;

public class testLambda{
	
	//匿名内部类
	@Test
	public void test1() {
		Comparator<Integer> com = new Comparator<Integer>() {

			@Override
			public int compare(Integer o1, Integer o2) {
				// TODO Auto-generated method stub
				return Integer.compare(o1, o2);
			}
		};
		
		TreeSet<Integer> ts = new TreeSet<>(com);
	}
	
	//Lambda表达式
	public void test2() {
		Comparator<Integer> com = (x,y) -> Integer.compare(x, y);
		TreeSet<Integer> ts = new TreeSet<>(com);
	}

实例:根据不同信息筛选当前员工资料。
创建员工类:


public class Employee {
	private String name;
	private int age;
	private double salary;
	/**
	 * @param name
	 * @param age
	 * @param salary
	 */
	public Employee(String name, int age, double salary) {
		super();
		this.name = name;
		this.age = age;
		this.salary = salary;
	}
	public Employee() {
		super();
		// TODO Auto-generated constructor stub
	}
	/**
	 * Get name.
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * Set the name.
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * Get age.
	 * @return the age
	 */
	public int getAge() {
		return age;
	}
	/**
	 * Set the age.
	 * @param age the age to set
	 */
	public void setAge(int age) {
		this.age = age;
	}
	/**
	 * Get salary.
	 * @return the salary
	 */
	public double getSalary() {
		return salary;
	}
	/**
	 * Set the salary.
	 * @param salary the salary to set
	 */
	public void setSalary(double salary) {
		this.salary = salary;
	}
}

员工信息:

List<Employee> employee = Arrays.asList(
			new Employee("张三", 18, 8000),
			new Employee("李四", 50, 10000),
			new Employee("王五", 45, 20000),
			new Employee("赵六", 19, 7500)
	);

筛选年龄大于35岁的员工:

@Test
	public void test3() {
		List<Employee> list = filterEmployees(employee);
		
		for(Employee employee : list) {
			System.out.println(employee);
		}
		
	}
	public List<Employee> filterEmployees(List<Employee> List){
		List<Employee> emps = new ArrayList<>();
		
		for(Employee emp : emps) {
			if(emp.getAge() >= 35) {
				emps.add(emp);
			}
		}
		return emps;
	}

但这样每有一个新需求就要写一个新方法,过于繁琐。

优化方法一:策略设计模式
创建泛型接口MyPredicate:

public interface MyPredicate<T>{
	public boolean test(T t);
}

创建FilterEmployeeByAge类继承MyPredicate接口,重写方法通过年龄筛选员工,根据其他信息筛选时只需再新建一个类继承MyPredicate:

public class FilterEmployeeByAge implements MyPredicate<Employee>{
	
	@Override
	public boolean test(Employee t) {
			return t.getAge() >= 35;
	}
}

只用写一个方法,通过创建类来实现接口:

@Test
	public void test4() {
		//通过年龄筛选
		List<Employee> list = filterEmployee(employee, new FilterEmployeeByAge());
		
		for(Employee employee : list) {
			System.out.println(employee);
		}
		
		//通过工资筛选
		List<Employee> list2 = filterEmployee(employee, new FilterEmployeeBySalary());
		
		for(Employee employee : list2) {
			System.out.println(employee);
		}
	}
	
	//只用写一个方法,只用创建类来实现接口
	public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> mp){
		List<Employee> emps = new ArrayList<>();
		
		for(Employee employee: list) {
			if(mp.test(employee)) {
				emps.add(employee);
			}
		}
		return emps;
	}

这种方法虽然只用写一个方法,但要新建多个类来实现不同需求,还是很麻烦

优化方法二:匿名内部类

//优化方法2:匿名内部类
	@Test
	public void test5() {
		List<Employee> list  = filterEmployee(employee, new MyPredicate<Employee>(){
			
			@Override
			public boolean test(Employee t) {
				return t.getSalary() <= 5000;
			}
		});
		
		for(Employee employee : list) {
			System.out.println(employee);
		}
	}

这种方法可读性较差

优化方法三:Lambda表达式

//优化方法3:Lambda表达式
	public void test6() {
		List<Employee> list  = filterEmployee(employee, (e) -> e.getSalary() <= 5000);
		list.forEach(System.out::println);
	}

优化方法四:Stream API

//优化方式4:Stream API
	@Test
	public void test7() {
		employee.stream()
		         .filter((e) -> e.getSalary() >= 5000)
		         .limit(2)
		         .forEach(System.out::println);
	}
上一篇:Java8新特性-日期时间


下一篇:手动上传SNAPSHOT文件到Maven私服Nexus的方法