java8 lambda表达式
lambda是一个匿名函数,先用以下的具体例子对比下
1.匿名内部类
原始方法
import org.junit.Test;
public class TestLambda {
@Test
public void test1() {
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
TreeSet<Integer> ts = new TreeSet<>(comparator);
}
}
lambda表达式优化
@Test
public void test2(){
Comparator<Integer> comparator = (x,y)-> Integer.compare(x,y);
TreeSet<Integer> treeSet = new TreeSet<>(comparator);
}
1.1实际案例:
筛选出一个公司中年龄大于30的人
Employee 类
@Data
@AllArgsConstructor
public class Employee {
private String name;
private Integer age;
private double salary;
}
1.1.1原始方法
测试方法
@Test
private void test3(){
Comparator<Integer> comparator = (x,y)-> Integer.compare(x,y);
TreeSet<Integer> treeSet = new TreeSet<>(comparator);
List<Employee> employees = Arrays.asList(
new Employee("张三",20,88.8),
new Employee("李四",30,88.8),
new Employee("王五",25,88.8),
new Employee("赵六",35,88.8),
new Employee("孙七",40,88.8)
);
List<Employee> result = filterByAge(employees);
System.out.println(result);
}
//筛选方法
public List<Employee> filterByAge(List<Employee> employees){
List<Employee> result = new ArrayList<>();
for (Employee em : employees) {
if (em.getAge()>30){
result.add(em);
}
}
return result;
}
如果有多个单独的条件筛选,这样就需要很多filterBy的方法,并且重复率很高
优化方式一:
1.1.2使用设计模式
定义接口
public interface MyPredicate<T> {
public boolean test(T t);
}
实现接口
public class FilterEmployeeByAge implements MyPredicate<Employee> {
@Override
public boolean test(Employee employee) {
return employee.getAge()>30;
}
}
过滤方法
public List<Employee> filter(List<Employee> employees,MyPredicate<Employee>mp){
List<Employee> result = new ArrayList<>();
for (Employee employee: employees) {
if (mp.test(employee)){
result.add(employee);
}
}
return result;
}
测试方法
@Test
public void test4(){
List<Employee> employees = Arrays.asList(
new Employee("张三",20,88.8),
new Employee("李四",30,88.8),
new Employee("王五",25,88.8),
new Employee("赵六",35,88.8),
new Employee("孙七",40,88.8)
);
List<Employee> result = filter(employees, new FilterEmployeeByAge());
System.out.println(result);
}
1.1.3基于设计模式使用匿名内部类
过滤方法
public List<Employee> filter(List<Employee> employees,MyPredicate<Employee>mp){
List<Employee> result = new ArrayList<>();
for (Employee employee: employees) {
if (mp.test(employee)){
result.add(employee);
}
}
return result;
}
测试方法
@Test
public void test5(){
List<Employee> employees = Arrays.asList(
new Employee("张三",20,88.8),
new Employee("李四",30,88.8),
new Employee("王五",25,88.8),
new Employee("赵六",35,88.8),
new Employee("孙七",40,88.8)
);
List<Employee> result = filter(employees, new MyPredicate<Employee>() {
@Override
public boolean test(Employee employee) {
return employee.getAge()>30;
}
});
System.out.println(result);
}
1.1.4lambda表达式优化
过滤方法
public List<Employee> filter(List<Employee> employees,MyPredicate<Employee>mp){
List<Employee> result = new ArrayList<>();
for (Employee employee: employees) {
if (mp.test(employee)){
result.add(employee);
}
}
return result;
}
测试方法
@Test
public void test6(){
List<Employee> employees = Arrays.asList(
new Employee("张三",20,88.8),
new Employee("李四",30,88.8),
new Employee("王五",25,88.8),
new Employee("赵六",35,88.8),
new Employee("孙七",40,88.8)
);
List<Employee> result = filter(employees,(employee) ->employee.getAge()>30);
System.out.println(result);
}
1.1.5 使用stream流优化
不需要过滤方法
@Test
public void test7(){
List<Employee> employees = Arrays.asList(
new Employee("张三",20,88.8),
new Employee("李四",30,88.8),
new Employee("王五",25,88.8),
new Employee("赵六",35,88.8),
new Employee("孙七",40,88.8)
);
employees.stream()
.filter((e)->e.getAge()>30)
.forEach(System.out::println);
}
2.表达式语法
->
lambda表达式操作符,将整个表达式分成两部分,左边的为参数列表,右边的为lambda体
使用同级别的变量时,变量默认时final修饰的
2.1语法格式一
无参数无返回值
lambda表达式时需要接口支持的,这里的接口只是做例子,对应无返回值无参数,不代表实际意义
@Test
public void test1() {
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("hello");
}
};
r1.run();
System.out.println("********************");
Runnable r2 = ()-> System.out.println("hello");
r2.run();
}
2.2 语法格式二
一个参数,无返回值
@Test
public void test2() {
Consumer consumer = (e)-> System.out.println(e);
consumer.accept("hello");
}
Consumer接口是专门支持lambda表达式的函数式接口,具体表现为:
使用@FunctionalInterface
注解,该接口只消费
主要的方法就是accept(),传入一个参数,无返回值
2.3语法格式三
有两个以上的参数,有返回值,并且有多条执行语句
执行语句需要使用大括号进行包裹
@Test
public void test3() {
Comparator<Integer> comparator = (x,y)->{
System.out.println("hello");
return Integer.compare(x,y);
};
comparator.compare(3,5);
}
Comparator也是函数式接口
2.4 语法格式四
如果参数只有一个,小括号可以不写,但习惯上都写
@Test
public void test2() {
Consumer consumer = e-> System.out.println(e);
consumer.accept("hello");
}
2.5 语法格式五
lambda体只有一个语句,大括号和return可以都不写
@Test
public void test4() {
Comparator<Integer> comparator = (x,y)->Integer.compare(x,y);
comparator.compare(3,5);
}
3.函数式接口
接口中只有一个抽象方法的接口,称为函数式接口,使用@FunctionalInterface
注解可以检查该接口是不是函数式接口
java内置的四大函数式接口
3.1 Consumer消费型接口
void accept(T t)
@Test
public void test1(){
consumer(10,(e)->{
System.out.println("输入的是"+e);
});
}
/**
* 定义一个方法
*/
private void consumer(Integer num , Consumer<Integer> consumer){
consumer.accept(num);
}
3.2 Supplier 供给型接口
T get()
@Test
public void test2(){
List<Integer> getlist = getlist(10, () -> (int) (Math.random()*100));
System.out.println(getlist);
}
private List<Integer> getlist(Integer num , Supplier<Integer> supplier){
List<Integer> list = new ArrayList();
for (int i = 0; i <num ; i++) {
Integer integer = supplier.get();
list.add(integer);
}
return list;
}
3.3 Function 函数型接口
R accept(T t)
@Test
public void test3(){
String lsdadasd = strHandler("lsdadasd", (str) -> str.toUpperCase());
System.out.println(lsdadasd);
}
private String strHandler(String string , Function<String,String> function){
return function.apply(string);
}
3.4 Predicate 断定型接口
boolean test(T t)
public void test4(){
List<String> list =Arrays.asList("l1","li2","lis3","list4");
List<String> result = strFilter(list, (str) -> str.length() > 3);
System.out.println(result);
}
private List<String> strFilter(List<String> list , Predicate<String> predicate){
List<String> result = new ArrayList<>();
for (String str:list) {
if (predicate.test(str)){
result.add(str);
}
}
return result;
}