一 . Lambda表达式简单概要
Lambda是一种匿名函数,可以理解为一种可传递的代码,可以写出更简洁,更灵活的代码。
二. Lambda表达式语法格式
- 举例:(o1,o2)-> Integer.compare(o1,o2);
语法格式:
-> : Lambda操作符 或 箭头操作符
-> 左边:Lambda形参列表(其实就是接口中的抽象方法的形参列表)
-> 右边:Lambda体(其实就是重写的抽象方法的方法体)
三. Lambda常用的几种情况
-
无形参,无返回值
Runnable r2 = () -> System.out.println(“方式二:上善若水”); -
有两个以上的形参,有返回值,方法体中只有一条执行语句,可以省略中括号
Comparator c2 = (o1, o2) -> Integer.compare(o1, o2); -
有一个形参,无返回值
Consumer c2 = s -> System.out.println(s);
四. 方法引用的3种情况
-
对象::实例方法 (对象调用非静态方法)
Consumer c2 = System.out::println; -
类::静态方法(类调用静态方法)
Comparator c3 = Integer::compare; -
类::非静态方法(类调用非静态方法,形参中有两个参数的情况,调用方是第一个参数类型)
Comparator c2= String::compareTo;
BiPredicate<String, String> func2 = String::equals; -
其中构造器引用和数组引用,写法与方法引用类型
五. 案例演示
@Test
public void test01() {
//方式一:普通写法(匿名内部类重写方法)
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("方式一:大道至简");
}
};
r1.run();
System.out.println("-----------------------");
//方式二:Lambda写法(没有形参,无返回值)
/**
* 注明:Lambda表达式简化代码,省略可以不用写的代码
* 如该案例:实现类已经由返回类型决定,且里面只有一个抽象方法,因此这些已经确认并不会改变的,既可以省略不写)
*/
Runnable r2 = () -> System.out.println("方式二:上善若水");
r2.run();
}
@Test
public void test02() {
//方式一:普通写法(匿名内部类重写方法)
Consumer<String> c1 = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
c1.accept("顺势而为");
System.out.println("-----------------------");
//方式二:Lambda写法(有一个形参,无返回值)
Consumer<String> c2 = s -> System.out.println(s);
c2.accept("有道无术");
}
@Test
public void test03() {
//方式一:普通写法(匿名内部类重写方法)
Comparator<Integer> c1 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
int compare = c1.compare(12, 21);
System.out.println(compare);
System.out.println("-----------------------");
//方式二:Lambda写法(有形参,有返回值)
Comparator<Integer> c2 = (o1, o2) -> Integer.compare(o1, o2);
int compare2 = c1.compare(21, 11);
System.out.println(compare2);
System.out.println("-----------------------");
//方式三:方法引用(类调用静态方法)
/**
* 注明:方法引用式是在lambda表达式的基础上再做简化的操作
* 1.当要传递给lambda表达式方法体的操作,已经有实现的的方法,则可以使用方法引用
* 2.要求:接口中的抽象方法的(形参列表和返回值类型)与方法引用的方法的(形参列表和返回值类型)一致
*/
Comparator<Integer> c3 = Integer::compare;
int compare3 = c1.compare(23, 40);
System.out.println(compare3);
}
@Test
public void test04() {
//lambda表达式的写法
Consumer<String> c1 = s -> System.out.println(s);
c1.accept("有道无术,术尚可求");
System.out.println("-------------------------");
//方法引用的写法(lambda表达式升级版)(情况一:对象调用非静态方法)
Consumer<String> c2 = System.out::println;
c2.accept("有术无道,止于术");
}
@Test
public void test05() {
//Lambda表达式的写法
Comparator<String> c1 = (t1, t2) -> t1.compareTo(t2);
System.out.println(c1.compare("abc", "abd"));
BiPredicate<String, String> func1 = (t3, t4) -> t3.equals(t4);
System.out.println(func1.test("111", "121"));
System.out.println("-------------------------");
//方法引用的写法(类调用非静态方法,形参中有两个参数的情况,调用方是第一个参数类型)
Comparator<String> c2 = String::compareTo;
System.out.println(c2.compare("abc", "abe"));
//方法引用的写法(形参中有两个参数的情况,调用方是第一个参数类型)
BiPredicate<String, String> func2 = String::equals;
System.out.println(func2.test("111", "111"));
}
/**
* 题目要求:一个集合,存储满足对应的条件的数据,使用函数式接口lambda表达式写代码
*/
@Test
public void lambdaTest01() {
List<String> list = Arrays.asList("北京", "天津", "南京", "东京");
List<String> filterList = filterString(list, str -> str.contains("京"));
System.out.println(filterList.toString());
}
//定义一个过滤字符串的方法,过滤字符串的规则由Predicate这个函数式接口定义
public List<String> filterString(List<String> list, Predicate<String> pre) {
ArrayList<String> list1 = new ArrayList<>();
for (String s : list) {
if (pre.test(s)) {
list1.add(s);
}
}
return list1;
}
@Test
public void test06(){
//普通方式
Function<Integer,User> func1 = new Function<Integer, User>() {
@Override
public User apply(Integer id) {
return new User(id);
}
};
System.out.println(func1.apply(1));
//lambda表达式写法
Function<Integer,User> func2 = id -> new User(id);
System.out.println(func2.apply(2));
//构造器引用(调用方为返回的类型)
Function<Integer,User> func3 = User::new;
System.out.println(func2.apply(3));
}
}