lambda
① 什么是lambda ?
Lambda表达式可以理解为是一段可以传递的代码(将代码像参数一样进行传递,称为行为参数化)。Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中)如下所示:
Comparator<Integer> comparable = (x,y) ->Integer.compare(x,y)
② lamda基础语法
在Java8中引入了一个新的操作符"->"该操作符成为lambda操作符,箭头将lambda表达式分为2部分:
(T … object) ->{ doSomething } [ () 里的为参数列表,每个参数以","分割,**{}**中的则为所需要执行功能 ,T表示类型]
**I.**左侧为lambda 表达式的参数列表
**II.**右侧为lambda 表达式所需要执行的功能,即 lambda体
什么东西可以省略不写?
I.Lambda表达式的参数列表的数据类型可以省略不写,因为在JVM编译器可以通过上下文推断出数据类型,即"类型推断"
Comparator<Integer> comparable = (Integer x, Integer y) -> {
System.out.println("x:" + x + ",y:" + y);
return Integer.compare(x, y);
};
//省略后
Comparator<Integer> comparable = ( x, y) -> {
System.out.println("x:" + x + ",y:" + y);
return Integer.compare(x, y);
};
**II.**参数只有一个时,可以省略(),lambda体只有一行时,可以省略{}
str -> System.out.println(str)
a.无参数无返回值
Runnable r1 = () ->{ System.out.println("这是一个无参无返回值的lambda表达式")};
b.有参无返回值
Consumer<String> consumer =(str) -> {System.out.println(str)};
c.无参有返回值
Supplier supplier=()-> {
String str = String.valueOf("这是一个无参,但有返回值的方法");
return str;
};
d.有参有返回值
Comparator<Integer> comparable = (x, y) -> {
System.out.println("x:" + x + ",y:" + y);
return Integer.compare(x, y);
};
e.参数只有一个,lambda体只有一行
x->System.out.println(x)
③ 为啥要用lambda?
举个例子,假设现在有一批学生,需要按照如下进行需求,进行过滤掉部分不满足条件的学生:
-
1.获取StuList中性别为女的学生
-
2.将StuList中年龄大于18的获取出来
后面要用到的student实体类
package com.example.java8.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; import lombok.experimental.Accessors; /** * 学生实体对象 * @author Y */ @Data @Accessors(chain=true) @AllArgsConstructor @NoArgsConstructor @ToString public class Student { /** * 姓名 */ private String name; /** * 性别 */ private String sex; /** * 年龄 */ private Integer age; /** * 比较年龄大小 * @param student1 学生1 * @param student2 学生2 * @return 学生1的年龄大于学生2的年龄则返回1,反之返回-1 相等返回0 */ public static int compareAsc(Student student1, Student student2) { return student1.getAge().compareTo(student2.getAge()); } /** * 比较年龄大小 * @param student1 学生1 * @param student2 学生2 * @return 学生12的年龄大于学生1的年龄则返回1,反之返回-1 相等返回0 */ public static int compareDesc(Student student1, Student student2) { return student2.getAge().compareTo(student1.getAge()); } }
先初始化一个学生List,用于后面要讲解的3种不同方式提供数据:
private static final String SEX_WOMEN = "女"; public static final Integer AGE_18 = 18; //初始化 private static List<Student> studentList = Arrays.asList( new Student("张三", "男", 16), new Student("李四", "男", 15), new Student("王五", "男", 17), new Student("张二麻子", "男", 18), new Student("大乔", "女", 18), new Student("小乔", "女", 17) );
基于传统的java代码编写(不含有设计模式、java8等等),方式一:
按照需求,分别写2个方法:按照性别过滤、按照年龄过滤
/** * 按照性别为女的过滤 与sex相同保留,反之丢弃 * @param studentList 要过滤的学生 * @param sex 性别 * @return 过滤完后的学生实体 */ private static List<Student> filterBySex(List<Student> studentList,String sex) { List<Student> resultList = new ArrayList<>(studentList.size()); for (Student student : studentList) { if (sex.equals(student.getSex())) { resultList.add(student); } } return resultList; } /** * 按照年龄过滤学生 --与age相等则保留 反之丢弃 * @param studentList 要过滤的学生实体 * @param age 过滤年龄 * @return 已经过滤后的学生实体 */ private static List<Student> filterByAge(List<Student> studentList,Integer age) { List<Student> resultList = new ArrayList<>(studentList.size()); for (Student student : studentList) { if (age.equals(student.getAge())) { resultList.add(student); } } return resultList; } //方式一: 按照需求定制化不同的方法 @Test private void test01(){ //打印性别为女的 System.out.println("方式一调用:"); for (Student filterBySex : filterBySex(studentList,SEX_WOMEN)) { System.out.println("性别为女的:" + filterBySex); } //打印年龄为18的 for (Student filterByAge : filterByAge(studentList,AGE_18)) { System.out.println("龄为18的:" + filterByAge); } }
基于匿名内部类进行编写:
新建一个用于条件判断的接口IMypredicate:
public interface IMypredicate {
/**
* 用于用户自定义过滤条件
*
* @param student 需要进行断言的学生
* @return 断言的结果
*/
boolean filter(Student student);
}
然后写一个filter方法,用于按用于自定义的predicate进行过滤studentList:
/**
* 自定义学生条件过滤方法
* @param studentList 要过滤的学生实体
* @param predicate 过滤条件
* @return 过滤完的学生
*/
private static List<Student> filter(List<Student> studentList, IMypredicate predicate) {
List<Student> resultList = new ArrayList<>(studentList.size());
for (Student student : studentList) {
if (predicate.filter(student)) {
resultList.add(student);
}
}
return resultList;
}
//方式二:
//提一个公有接口IMypredicate出来,定义一个方法filter,后面要按照某种条件直接实现内部类即可
@Test
private void test02(){
System.out.println("方式二调用:");
List<Student> filterBySex = filter(studentList, new IMypredicate() {
@Override
public boolean filter(Student student) {
return SEX_WOMEN.equals(student.getSex());
}
});
for (Student bySex : filterBySex) {
System.out.println("性别为女的:" + bySex);
}
//获取年龄为18的
List<Student> filterByAge = filter(studentList, new IMypredicate() {
@Override
public boolean filter(Student student) {
return AGE_18.equals(student.getAge());
}
});
for (Student byByAge : filterByAge) {
System.out.println("年龄为18的:" + byByAge);
}
}
基于lambda表达式:
//方式三:
//lambda表达式写法
@Test
private void test03() {
//方式三(lambda):
//过滤性别
filter(studentList, student -> SEX_WOMEN.equals(student.getSex()));
//获取年龄大于15
filter(studentList, student -> student.getAge() > 15);
//获取年龄大于15 且为女的学生
filter(studentList, student -> student.getAge() > 15 && student.getSex().equals(SEX_WOMEN));
}