概述
JAVA8中引入了一个新的操作符“->”,该操作符称为箭头操作符或Lambda操作符,箭头操作符将Lambda表达式拆分成两部分
左侧: Lambda表达式的参数列表
右侧: Lambda表达式中所需要执行的功能,即Lambda体
所谓Lambda表达式就是接口的实现的一种方式,Lambda表达式的参数列表就是接口中抽象方法的参数列表,Lambda表达式中所需要执行的功能就是接口中抽象方法具体实现要执行的功能
测验:Lambda语法
根据上述语法规则,以下哪个不是有效的Lambda表达式?
(1) () -> {}
(2) () -> "Raoul"
(3) () -> {return "Mario";}
(4) (Integer i) -> return "Alan" + i;
(5) (String s) -> {"IronMan";}
答案:只有4和5是无效的Lambda。
(1) 这个Lambda没有参数,并返回void。它类似于主体为空的方法:public void run() {}。
(2) 这个Lambda没有参数,并返回String作为表达式。
(3) 这个Lambda没有参数,并返回String(利用显式返回语句)。
(4) return是一个控制流语句。要使此Lambda有效,需要使花括号,如下所示:
(Integer i) -> {return "Alan" + i;}。
(5)“Iron Man”是一个表达式,不是一个语句。要使此Lambda有效,你可以去除花括号
和分号,如下所示:(String s) -> "Iron Man"。或者如果你喜欢,可以使用显式返回语
句,如下所示:(String s)->{return "IronMan";}。
语法格式
语法格式一 :实现的接口无参 无返回值
左侧直接写() ,右侧是实现接口的功能
() -> System.out.println("Hello Lambda");
以Runable接口为例
/**
* @author Dongguo
* @date 2021/8/14 0014 16:20
* @description:语法格式一:无参数,无返回值 ()->System.out.println("Hello world");
*/
@Test
public void test1() {
Runnable runnable1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello world");
}
};
runnable1.run();
System.out.println("----------------");
Runnable runnable2 = () -> System.out.println("Hello world");
runnable2.run();
}
语法格式二 :实现的接口有一个参数 无返回值
(X) -> System.out.println(x);
以Consumer接口为例
/**
* @author Dongguo
* @date 2021/8/14 0014 16:27
* @description:语法格式二:有一个参数,无返回值 (t)->System.out.println("Hello world");
*/
@Test
public void test2(){
Consumer<String> consumer = (x)-> System.out.println(x);
consumer.accept("Hello world");
System.out.println("------------");
//如果只有一个参数 ()可以省略
Consumer<String> consumer2 = x-> System.out.println(x);
consumer2.accept("Hello world2");
}
}
语法格式三 :若实现的接口有且只有一个参数 左侧()可以省略
X -> System.out.println(x);
@Test
public void test3(){
Consumer<String> con = x -> System.out.println(x);
con.accept("Hello Lambda");
}
运行结果:
Hello Lambda
语法格式四 :有两个及以上的参数,有返回值,并且Lambda体中有多条语句
Comparator<Integer> com = (x, y) -> {
System.out.println("Hello Lambda");
return Integer.compare(x,y);
以Comparator接口为例
@Test
public void test3(){
Comparator<Integer> comparator = (o1,o2)->{
System.out.println("比较两个值");
return Integer.compare(o1,o2);
};
}
语法格式五:有两个以上的参数,有返回值,并且Lambda体中只有一条语句 {}和return 可以省略
(x, y) -> Integer.compare(x,y);
@Test
public void test5() {
Comparator<Integer> com = (x, y) -> Integer.compare(x,y);
}
语法格式六:Lambda 表达式的参数列表的数据类型可以省略不写 ,因为jdk1.8 JVM编译器可以通过上下文推断出数据类型,即“类型推断”
( x, y) -> Integer.compare(x,y);
@Test
public void test6() {
//省略前
Comparator<Integer> com = (Integer x,Integer y) -> Integer.compare(x,y);
//省略后
Comparator<Integer> com1 = (x, y) -> Integer.compare(x,y);
//比如 以下都是通过上下文推断出类型
String[] strs = {"aaa","bbb","ccc"};
List<String> list = new ArrayList<>();
show(new HashMap<>());
}
public void show(Map<String,Integer> map){
}
总结:
上联:左右遇一括号省
下联:左侧推断类型省
横批: 能省则省
lambda表达式需要函数式接口的支持
函数式接口:接口中只有一个抽象方法的接口,称为函数式接口
可以使用注解@FunctionalInterface 修饰,声明只能有一个抽象方法,可以检查是否为函数式接口
之前创建的MyPredicate接口就是函数式接口
@FunctionalInterface//检查是否是函数式接口
public interface MyPredicate<T> {
public boolean predicate(T t);
}
练习:
需求1:对一个数进行运算
使用Lambda表达式,创建一个函数式接口
package com.dongguo.java8.employee;
/**
* @author Dongguo
* @date 2021/8/14 0014-16:50
* @description:分析:对一个数进行运算,接收一个数字进行运算后并返回
*/
@FunctionalInterface
public interface MyFunction {
Integer getValue(Integer num);
}
/**
* @author Dongguo
* @date 2021/8/14 0014 16:51
* @description:需求:对一个数进行运算
*/
@Test
public void test4() {
Integer num = 10;
//对数字+100
Integer i = operation(num, (n) -> n + 100);
System.out.println(i);
}
/**
* @author Dongguo
* @date 2021/8/15 0015 16:21
* @description:接受一个字符串,处理后并返回
*/
public static Integer operation(Integer num, MyFunction function) {
return function.getValue(num);
}
需求2,调用Collections.sort()方法,通过定制排序比较两个Employee (先按年龄比,年龄相同按姓名比),使用Lambda作为参数传递。
List<Employee> employees = Arrays.asList(new Employee("张三", 20, 3000),
new Employee("张三", 18, 4000),
new Employee("李四", 28, 5000),
new Employee("王五", 58, 6000),
new Employee("赵六", 48, 5500),
new Employee("田七", 38, 4500));
@Test
public void test5() {
Collections.sort(employees,(e1,e2)->{
if (e1.getAge() == e2.getAge()){
return e1.getName().compareTo(e2.getName());
}
return Integer.compare(e1.getAge(),e2.getAge());
});
System.out.println(employees);
}
运行结果
[Employee{name='张三', age=18, salary=4000}, Employee{name='张三', age=20, salary=3000}, Employee{name='李四', age=28, salary=5000}, Employee{name='田七', age=38, salary=4500}, Employee{name='赵六', age=48, salary=5500}, Employee{name='王五', age=58, salary=6000}]
需求3.①声明函数式接口,接口中声明抽象方法, public String getValue(String str):
②声明类TestLambda ,类中编写方法使用接口作为参数,将一个字符串转换成大写,并作为方法的返回值。.
③再将一个字符串的第2个和第4个索引位置进行截取子串。
@FunctionalInterface
public interface MyFun {
String getValue(String str);
}
/**
* @author Dongguo
* @date 2021/8/14 0014 17:47
* @description:处理字符串
*/
public static String stringToUpper(String s, MyFun fun) {
return fun.getValue(s);
}
@Test
public void test6() {
String str = "abcdefg";
String s = stringToUpper(str, (x) -> x.toUpperCase());
System.out.println(s);
String s1 = stringToUpper(str, (x) -> x.substring(1, 3));
System.out.println(s1);
}
运行结果
ABCDEFG
bc
需求4.①声明一个带两个泛型的函数式接口,泛型类型为<T, R> T为参数, R为返回值.②接口中声明对应抽象方法③在TestLambda类中声明方法,使用接口作为参数,计算两个long型参数的和。④再计算两个long型参数的乘积。..
@FunctionalInterface
public interface MyFun2<T, R> {
R getValue(T t1, T t2);
}
public static long op(long l1, long l2, MyFun2<Long,Long> function2){
return function2.getValue(l1,l2);
}
@Test
public void test7() {
long l1 = 20L;
long l2 = 15L;
long op1 = op(l1, l2, (x1, x2) -> x1 + x2);
System.out.println(op1);
long op2 = op(l1, l2, (x1, x2) -> x1 * x2);
System.out.println(op2);
}
运行结果
35
300
最后
以上就是美丽流沙为你收集整理的Lambda基础语法语法格式 lambda表达式需要函数式接口的支持练习:的全部内容,希望文章能够帮你解决Lambda基础语法语法格式 lambda表达式需要函数式接口的支持练习:所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复