一,接口的默认方法
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);
}