Lambda表达式入门
本质
Lambda 表达式需要“函数式接口”的支持
函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。可以使用注解@FunctionalInterface 修饰可以检查是否是函数式接口
语法学习
Lambda 表达式的基础语法:Java8中引入了一个新的操作符“->”该操作符称为箭头操作符或Lambda 操作符:
操作符将Lambda表达式拆分两部分:
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需要执行的功能,即Lambda 体
语法格式一:无参数,无返回值
()-> System.out.println(“hello Lambda!”);
int num = 520; //JDK1.7前,必须是final,不能被修改
@Test
public void test1(){
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("hello world!"+num);
}
};
r1.run();
System.out.println("-------------------------");
Runnable r2 = () -> System.out.println("hello Lambda!"+num);
r2.run();
}
语法格式二:有一个参数并且无返回值。
(x)-> System.out.println(x);
@Test
public void test2(){
Consumer<String> con = (x) -> System.out.println(x);
con.accept("我要好好学习!");
}
语法格式三:若只有一个参数,小括号可以省略不写。
x -> System.out.println(x);
语法格式四:有两个以上的参数,有返回值,Lambda 体中有多条执行语句
@Test
public void test3(){
Comparator<Integer> com = (x,y) -> {
System.out.println("函数式接口");
return Integer.compare(x,y);
};
}
语法格式五:若Lambda 体中只有一条语句,return 和 {}都可以省略不写。
语法格式六: Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编 译器通过上下文推断出数据类型 即“类型推断”。
练习
1. 需求:对一个数进行运算
1.声明一个接口
@FunctionalInterface
public interface MyFun {
public Integer getValue(Integer num);
}
2.测试代码
// 需求:对一个数进行运算
@Test
public void test6(){
// 乘法
Integer num1 = operation(100, (x) -> x * x);
System.out.println(num1);
//加法
Integer num2 = operation(200, (y) -> (y + 200));
System.out.println(num2);
}
public Integer operation(Integer num, MyFun mf){
return mf.getValue(num);
}
2. 调用Collections.sort()方法,通过定制排序比较两个employee(先按年龄比,年龄相同按姓名比),使用 Lambda 作为参数传递。
List<Employee> emps = Arrays.asList(
new Employee("张三",18,9999.99),
new Employee("李四",38,4555.66),
new Employee("王五",50,6666.66),
new Employee("赵六",16,7777.77),
new Employee("田七",8,8888.88)
);
@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);
}
}
java8 内置的四大核心函数式接口
1. 消费型接口
// 消费型接口 Comsumer<T>
@Test
public void test1(){
happy(1000000, (m) -> System.out.println("今天买了一辆车消费了"+m+"元"));
}
public void happy(double money, Consumer<Double> con){
con.accept(money);
}
2. 供给型接口
// 供给型接口 Supplier<T>
@Test
public void test2(){
List<Integer> numList = getNumList(10, () -> (int) (Math.random() * 100));
for (Integer num : numList) {
System.out.println(num);
}
}
// 需求:产生指定个数的整数,并放入集合中
public List<Integer> getNumList(int num, Supplier<Integer> sup){
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
Integer integer = sup.get();
list.add(integer);
}
return list;
}
3. 函数型接口
// 函数型接口 Function<T,R>
@Test
public void test3(){
String s = strHanlder("\t\t\t\t 我要好好学习! ", (str) -> str.trim());
System.out.println(s);
String s1 = strHanlder("爱你一万年是不可能的!", (str) -> str.substring(0, 5));
System.out.println(s1);
}
// 需求:用于处理字符串
public String strHanlder(String str, Function<String, String> fun){
String s = fun.apply(str);
return s;
}
4. 断言型接口
// Predicate<T> 断言型接口
@Test
public void test4(){
List<String> list = Arrays.asList("hello", "world", "perfect", "ok", "am");
List<String> stringList = filterStr(list, (s) -> s.length() > 3);
for (String s : stringList) {
System.out.println(s);
}
}
// 需求:将满足条件的字符串放到集合中
public List<String> filterStr(List<String> list, Predicate<String> pre){
List<String> strList = new ArrayList<>();
for (String str : list) {
if(pre.test(str)){
strList.add(str);
}
}
return strList;
}