1.概述
Lambda是一个匿名函数,是java8的一个新特性。可以对接口进行非常简洁的实现。但它要求接口中只能有一个抽象方法,原因是lambda只能实现一个方法。另外,需要在接口上添加注解@FunctionalInterface,添加此注解,也是说明此接口可以通过labmda进行实现,也就限制了此接口只能有一个抽象方法,如果有多个就会报错。
2.基础语法
2.1无参无返回值
接口:
@FunctionalInterface public interface MyLambda { void test(); }
调用:
public static void main(String[] args) { //创建对象 MyLambda lambda = () -> { System.out.println("我是无参无返回值的方法"); }; //调用方法 lambda.test(); }
2.2无参有返回值
接口:
@FunctionalInterface public interface MyLambda { int test(); }
调用:
public static void main(String[] args) { //创建对象 MyLambda lambda = () -> { System.out.println("我是无参有返回值的方法"); return 1; }; //调用方法 System.out.println(lambda.test()); }
2.3单参无返回值
接口:
@FunctionalInterface public interface MyLambda { void test(int a); }
调用:
public static void main(String[] args) { //创建对象 MyLambda lambda = (int a) -> { System.out.println("我是单参无返回值的方法,参数是:"+a); }; //调用方法 lambda.test(10); }
2.4多参无返回值
接口:
@FunctionalInterface public interface MyLambda { void test(int a,int b,int c); }
调用:
public static void main(String[] args) { //创建对象 MyLambda lambda = (int a,int b,int c) -> { System.out.println("我是多参无返回值的方法,参数是:"+a+","+b+","+c); }; //调用方法 lambda.test(10,20,15); }
2.5单参有返回值
接口:
@FunctionalInterface public interface MyLambda { int test(int a); }
调用:
public static void main(String[] args) { //创建对象 MyLambda lambda = (int a) -> { System.out.println("我是单参有返回值的方法,参数是:"+a); return a*3; }; //调用方法 System.out.println(lambda.test(10)); }
2.6多参有返回值
接口:
@FunctionalInterface public interface MyLambda { int test(int a,int b,int c); }
调用:
public static void main(String[] args) { //创建对象 MyLambda lambda = (int a,int b,int c) -> { System.out.println("我是多参有返回值的方法,参数是:"+a+","+b+","+c); return a+b+c; }; //调用方法 System.out.println(lambda.test(10, 20, 15)); }
2.7语法简化
1)参数类型。由于在接口的抽象方法中已经定义了参数的类型,那么在lambda中就可以省略参数。需要注意的是,如果要省略参数类型,就必须省略全部的参数类型。
2)参数小括号。如果参数只有一个时,可以省略小括号。
3)参数大括号。如果方法体中只有一条语句,可以省略大括号。如果需要返回值,则要同时省略return关键字。
实例1:参数类型省略
public static void main(String[] args) { //创建对象 MyLambda lambda = (a) -> { return a*3; }; //调用方法 System.out.println(lambda.test(10)); }
实例2:参数小括号省略
public static void main(String[] args) { //创建对象 MyLambda lambda = a -> { return a*3; }; //调用方法 System.out.println(lambda.test(10)); }
实例3:参数大括号省略
public static void main(String[] args) { //创建对象 MyLambda lambda = a -> a * 3; //调用方法 System.out.println(lambda.test(10)); }
2.8方法的引用
它的作用是把一个lambda表达式实现指向一个已经实现的方法。
语法:方法的隶属者::方法名
先看下面的一个实例:接口参考2.6。
public static void main(String[] args) { //创建对象 MyLambda lambda = (a,b,c) -> a+b+c; //创建对象 MyLambda lambda2 = (a,b,c) -> a+b+c; //调用方法 System.out.println(lambda.test(10,30,20)); }
如果在一个方法中对接口进行多次的实现,方法体的内容是一样的,写的也是比较麻烦的,那么此时就可以把方法体的内容写到一个新的方法中,然后去调用方法即可,再次调用时使用方法的引用就好。
public class LambdaTest { public static void main(String[] args) { //创建对象 MyLambda lambda = (a,b,c) -> add(a,b,c); //方法的引用,类名::方法名 MyLambda lambda2 = LambdaTest::add; //调用方法 System.out.println(lambda.test(10,30,20)); System.out.println(lambda2.test(10,30,20)); } private static int add(int a,int b,int c){ return a+b+c; } }
3.核心函数式接口
3.1说明
在java中有四大内置的函数式接口,为接口的实现提供了方便,见下表:
接口名 | 方法 | 参数 | 返回值 | 说明 |
Predicate
|
boolean test(T t);
|
T | boolean | 断言型接口 |
Consumer
|
void accept(T t);
|
T | 无 | 消费型接口 |
Function
|
R apply(T t)
|
T、R | R | 函数型接口 |
Supplier
|
T get();
|
无 | T | 供给型接口 |
这些接口的使用下面详细介绍。
3.2Predicate
//将满足条件的字符串,放到集合中 public List<String> filterStr(List<String> list, Predicate<String> pre){ List<String> newList=new ArrayList<>(); for (String str:list) { if(pre.test(str)){ newList.add(str); } } return newList; } @Test public void test(){ List<String> list= Arrays.asList("idea","eclipse","predicate","function"); List<String> returnList= filterStr(list,(str)->str.length()>4); for (String str:returnList) { System.out.println(str); } }
3.3Consumer
//对接口进行实现 public void shopping(double money, Consumer<Double> con) { con.accept(money); } @Test public void test() { shopping(1000, x -> System.out.println("今天购物花了" + x + "元")); }
3.4Function
//处理字符串 public String handlerStr(String str, Function<String,String> fun){ return fun.apply(str); } @Test public void test(){ String newStr= handlerStr("hello world,lambda",(str)->str.substring(3,6)); System.out.println(newStr); }
3.5Supplier
//产生指定个数的整数,放到集合中并返回 public List<Integer> getNumList(int num, Supplier<Integer> sup) { List<Integer> list = new ArrayList<>(); for (int i = 0; i < num; i++) { Integer n = sup.get(); list.add(n); } return list; } @Test public void test() { List<Integer> numList = getNumList(3, () -> (int) (Math.random() * 10)); for (Integer n : numList) { System.out.println(n); } }
4.lambda综合应用
4.1forEach遍历集合
Map<String, Integer> map = new HashMap<>(); map.put("zhangs", 20); map.put("lisi", 10); map.put("wangwu", 40); map.put("liliu", 30); map.forEach((key, value) -> System.out.println(key + "," + value));
集合可以使用forEach方法遍历,这里主要介绍遍历map。
4.2集合list排序
List<Integer> list = Arrays.asList(10, 50, 30, 20, 15, 80, 90); list.sort((o1, o2) -> o1 - o2); System.out.println(list);
4.3集合treeSet排序
TreeSet<Integer> set = new TreeSet<>((o1, o2) -> { if (o1 <= o2) { return -1; } else { return 1; } }); set.add(10); set.add(15); set.add(20); set.add(10); set.add(50); set.add(30); set.add(9); System.out.println(set);
4.4removeIf()
删除集合中符合条件的方法
List<Integer> list = new ArrayList<>(); list.add(10); list.add(50); list.add(30); list.add(20); list.add(15); list.add(80); list.add(90); //删除小于50的元素 list.removeIf(o -> o < 50); System.out.println(list);
4.5开启线程
Thread thread=new Thread(()->{ for (int i = 0; i < 20; i++) { System.out.println(i); } }); thread.start();