一:官方定义
Lambda 表达式 − Lambda允许把函数作为一个方法的参数(函数)作为参数传递进方法中。
该表达式的目的是:优化我们的代码,使我们的代码更加的简洁。
举例说明:
//使用java7排序
private void sortUsingJava7(List<String> names){
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
}
// 使用 java 8 排序
private void sortUsingJava8(List<String> names){
Collections.sort(names, (s1, s2) -> s1.compareTo(s2));
}
在7/8中我们看出来实则区别就是 对于Collections.sort(..)方法的调用。在使用 new Comparator<String>() 直接将参数转换成行为方法。
二:分析
1.线上代码:(其中User(id ->String ,name -> String ,age -> int))
public static void main(String[] args) {
List<User> list = new ArrayList<>();
User user1 = new User("1", "u1", 15);
User user2 = new User("2", "u2", 15);
User user3 = new User("2", "u3", 15);
User user4 = new User("4", "u4", 16);
User user5 = new User("5", "u5", 16);
User user6 = new User("6", "u6", 16);
User user7 = new User("7", "u7", 16);
User user8 = new User("8", "u8", 17);
User user9 = new User("9", "u9", 17);
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
list.add(user5);
list.add(user6);
list.add(user7);
list.add(user8);
list.add(user9);
}
2.下面定义一个一个方法:取出年龄大于15的所有的User
/**
* 取出年龄大于15的所有的User
* @param age
* @param userlist
* @return
*/
public List<User> getUser(Integer age,List<User> userlist){
List<User> list=new ArrayList<User>();
for(User user:userlist) {
if(user.getAge() >= age) {
list.add(user);
}
}
return list;
}
3.下面要求取出年龄大于15且名字不为张三的所有user
/**
* 取出年龄大于15且名字不为张三的所有user
* @param age
* @param userlist
* @return
*/
public List<User> getUser2(Integer age,String userName,List<User> userlist){
List<User> list=new ArrayList<User>();
for(User user:userlist) {
if(user.getAge() >= age && !user.getUserName() .equals("张三")) {
list.add(user);
}
}
return list;
}
4.这是如果要求:取出年龄大于15且名字不为张三且id大于100的用户呢?
明显又要创建新的方法或者改造老方法,很烦是不是?在java8之前,使用了接口然后实现其中的方法。
a.定义一个过滤机接口
//过滤接口---满足条件
interface userFilter{ boolean accep(User user);}
b.实现过滤
//过滤实现的方法
static List<User> userfilter(List<User> userList,userFilter userFiler){
List<User> resList=new ArrayList<User>();
for(final User user:userList) {
if(userFiler.accep(user)) {
resList.add(user);
}
}
return resList;
}
c.实现应用
public static void main(String[] args) {
List<User> list = new ArrayList<>();
User user1 = new User("1", "u1", 15);
User user2 = new User("2", "u1", 15);
User user3 = new User("2", "u3", 15);
User user4 = new User("4", "u4", 16);
User user5 = new User("5", "u5", 16);
User user6 = new User("6", "u6", 16);
User user7 = new User("7", "u7", 16);
User user8 = new User("8", "u8", 17);
User user9 = new User("9", "u9", 17);
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
list.add(user5);
list.add(user6);
list.add(user7);
list.add(user8);
list.add(user9);
//实现过滤,重写过滤条件
List<User> resUser=userfilter(list, new userFilter() {
@Override
public boolean accep(User user) {
return user.getAge() ==15 && user.getUserName().equals("u1");
}
});
}
很明显,我们过滤的时候只要实现userFilter接口中的数据就可以的。看到上述的代码是不是很熟悉,对java中实现list根据某
一 个元素排序就是这么做的。这时候我们使用lambda实现代码简化:我想能看懂了吧。
List<User> resUser2=userfilter(list, (User user) -> user.getAge() == 15 && user.getUserName().equals("u1"));
本节完整代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Test {
/**
* 取出年龄大于15的所有的User
* @param age
* @param userlist
* @return
*/
public List<User> getUser(Integer age,List<User> userlist){
List<User> list=new ArrayList<User>();
for(User user:userlist) {
if(user.getAge() >= age) {
list.add(user);
}
}
return list;
}
/**
* 取出年龄大于15且名字不为张三的所有user
* @param age
* @param userlist
* @return
*/
public List<User> getUser2(Integer age,String userName,List<User> userlist){
List<User> list=new ArrayList<User>();
for(User user:userlist) {
if(user.getAge() >= age && !user.getUserName() .equals("张三")) {
list.add(user);
}
}
return list;
}
//过滤接口
interface userFilter{ boolean accep(User user);}
//过滤实现的方法
static List<User> userfilter(List<User> userList,userFilter userFiler){
List<User> resList=new ArrayList<User>();
for(final User user:userList) {
if(userFiler.accep(user)) {
resList.add(user);
}
}
return resList;
}
public static void main(String[] args) {
List<User> list = new ArrayList<>();
User user1 = new User("1", "u1", 15);
User user2 = new User("2", "u1", 15);
User user3 = new User("2", "u3", 15);
User user4 = new User("4", "u4", 16);
User user5 = new User("5", "u5", 16);
User user6 = new User("6", "u6", 16);
User user7 = new User("7", "u7", 16);
User user8 = new User("8", "u8", 17);
User user9 = new User("9", "u9", 17);
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
list.add(user5);
list.add(user6);
list.add(user7);
list.add(user8);
list.add(user9);
//实现过滤,重写过滤条件
List<User> resUser=userfilter(list, new userFilter() {
@Override
public boolean accep(User user) {
return user.getAge() ==15 && user.getUserName().equals("u1");
}
});
//使用lambda简化 实现过滤,重写过滤条件
List<User> resUser2=userfilter(list, (User user) -> user.getAge() == 15 && user.getUserName().equals("u1"));
System.out.println(resUser);
System.out.println(resUser2);
}
}
d.基于上述的list,我们来使用lamdba重写list的sort方法
List<User> list = new ArrayList<>();
User user1 = new User("1", "u1", 1);
User user2 = new User("2", "u1", 2);
User user3 = new User("2", "u3", 3);
User user4 = new User("4", "u4", 4);
User user5 = new User("5", "u5", 5);
User user6 = new User("6", "u6", 6);
User user7 = new User("7", "u7", 7);
User user8 = new User("8", "u8", 8);
User user9 = new User("9", "u9", 9);
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
list.add(user5);
list.add(user6);
list.add(user7);
list.add(user8);
list.add(user9);
//原始方法
list.sort(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
if(o1.getAge() > o2.getAge()) {
return -1;
}
if(o1.getAge() < o2.getAge()) {
return 1;
}
if(o1.getAge() == o2.getAge()) {
return -0;
}
return 0;
}
});
//表达式
list.sort((User u1,User u2)-> u2.getAge() - u1.getAge());
System.out.println(list);
}
三:lambda表达式
1.基于上述的使用:
我们看到一半对于方法中有抽象的实现比如:方法名称(需要处理的对象,接口<参数>{方法的具体实现;})
转化成lambda表达式:方法名称(需要处理的对象,(参数)->(方法的具体实现)),其中上关于对象集合的过滤就是如此。
或者 需要处理的对象.方法名(接口<参数>{方法的具体实现 ;}) 转化 需要处理的对象.方法名((参数)->(具体的实现)),如
上述的对于list集合的排序就是如此。
2.lambda表达式
a.简而言之就是:参数列表 -> 表达式 /参数列表 -> {表达式集合}
3.基于函数式接口使用lambda
a。自定义函数式接口,比如我们第一个用户过滤接口
@FunctionalInterface
interface userFilter{ boolean accep(User user);}
其中@FunctionalInterface接口可有可无,但是当有注解时,接口只允许有一个抽象方法,否则会报错。
b.基于jdk自带的函数式接口(部分)
4.lambda使用注意事项
类型推断、局部变量
四:方法的引用
有时候,我们需要在lambo中引用类方法,使用方式 类名::方法名称
说实话,lambda表达式处理一些内部类是可以的,如果太较真就没必要了。