Lambda表达式
java 8 新特性简介
Lambda表达式
Lambda 是一个 匿名函数,我们可以把 Lambda 表达式理解为是 一段可传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到提升。
举例1 匿名类
//匿名类到Lambda的转换
Runnable runnable=new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类转换案例");
}
};
Runnable runnable1=()->{
System.out.println("匿名内部类转换案例");
};
new Thread(runnable).start();
new Thread(runnable1).start();
案例二 匿名类做参数传递
//使用匿名内部类作为参数传递
TreeSet<String> treeSet=new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(),o2.length());
}
});
TreeSet<String> treeSet1=new TreeSet<>(
(o1,o2)-> Integer.compare(o1.length(),o2.length())
);
Lambda 表达式:
在Java 8 语言中引入的一种新的语法元素和作符。这个操作符为 “->” , 该操作符被称为 Lambda 操作或 箭 头操作符。它将 Lambda 分为两个部分:
左侧:指定了 Lambda 表达式需要的参 参 数 列表
右侧:指定了 Lambda 体,是抽象方法的实现逻辑,也Lambda 表达式要执行的功能。
语法一:无参,无返回值
//无参,无返回值
Runnable runnable2=()->{
System.out.println("无参,无返回值");
};
语法二:一个参数,无返回值
//一个参数,无返回值
Consumer<String> consumer=(String str)->{
System.out.println("一个参数,无返回值");
};
语法三:一个参数(数据类型可省略),无返回值
//一个参数(数据类型可省略),无返回值
Consumer<String> consumer=(str)->{
System.out.println("一个参数(数据类型可省略,由编译器推断,称类型推断),无返回值");
};
上述 Lambda 表达式中的参数类型都是由编译器推断得出的。Lambd表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程的上下文,在后台推断出了参数的类型。Lambda 表达式的类型依赖上下文环境,是由编译器推断出来的。这就是所谓的“类型推断”
语法四:一个参数(数据类型可省略,小括号可省略),无返回值
//一个参数(数据类型可省略,小括号可省略),无返回值
Consumer<String> consumer= str ->{
System.out.println("一个参数(数据类型可省略,小括号可省略),无返回值");
};
语法五: 两个及以上参数,可以有返回值
//两个及以上参数,可以有返回值
Comparator<String> comparator=(o1,o2)->{
return Integer.compare(o1.length(),o2.length());
};
语法六:只有一条语句{}可省略
//只有一条语句{}可省略
Comparator<String> comparator=(o1,o2)->
Integer.compare(o1.length(),o2.length());
;
Lambda举例
- 调用 Collections.sort()方法,通过定制排序比较两个Employee(先按年龄比,年龄相同按姓名比),使用 Lambda 表达式作为参数传递。
- ① 声明函 数式接口 ,接口 中声明抽 象方法 : public String
getValue(String str);
②声明类 LambdaTest,类中编写方法使用接口作为参数,将一个字符串转换成大写,并作为方法的返回值。
③再将一个字符串的第 2 个到第 4 个索引位置进行截取子串。 - ①声明一个带两个泛型的函数式接口,泛型类型为<T,R> : T 为参
数,R 为返回值。
②接口中声明对应抽象方法
③在 LambdaTest 类中声明方法,使用接口作为参数,计算两个 long型参数的和。
④再计算两个 long 型参数的乘积
第二题接口
@FunctionalInterface
public interface MyFunction {
public String getValue(String str);
}
第三题接口
public interface MyFunction2<T, R> {
public R getValue(T t1, T t2);
}
具体实现:
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import com.atguigu.java1.Employee;
public class LambdaTest {
List<Employee> emps = Arrays.asList(
new Employee(101, "张三", 18, 9999.99),
new Employee(102, "李四", 59, 6666.66),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "赵六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);
//练习1
@Test
public void test1(){
Collections.sort(emps, (e1, e2) -> {
if(e1.getAge() == e2.getAge()){
return e1.getName().compareTo(e2.getName());
}else{
return -Integer.compare(e1.getAge(), e2.getAge());
}
});
for (Employee emp : emps) {
System.out.println(emp);
}
}
//练习2
@Test
public void test2(){
String trimStr = strHandler("\t\t\t 空格测试 ", (str) -> str.trim());
System.out.println(trimStr);
String upper = strHandler("abcdef", (str) -> str.toUpperCase());
System.out.println(upper);
String newStr = strHandler("世界那么大,我想去看看", (str) -> str.substring(2, 5));
System.out.println(newStr);
}
//需求:用于处理字符串
public String strHandler(String str, MyFunction mf){
return mf.getValue(str);
}
//练习3
@Test
public void test3(){
op(100L, 200L, (x, y) -> x + y);
op(100L, 200L, (x, y) -> x * y);
}
//需求:对于两个 Long 型数据进行处理
public void op(Long l1, Long l2, MyFunction2<Long, Long> mf){
System.out.println(mf.getValue(l1, l2));
}
}