- 初识Lambda
可以把lambda表达式理解为是可以传递匿名函数的一种方式:他没有名称,但有参数列表,函数主体,返回类型等
Lambda核心思想:
-
确认 Lamda 表达式的类型
-
找到要实现的方法
-
实现这个方法
Java8 中引入了一个新的 *** 作符 “->” , 该 *** 作符称为箭头 *** 作符或 Lambda *** 作符,该 *** 作符将 Lambda 表达式分为两部分:
左侧:函数式接口中抽象方法的参数列表
右侧:对函数式接口中抽象方法的实现,即 Lambda 体
小例子
(String s) -> s.length //返回int,其中隐含了return (Apple a) -> a.getWight() > 100 //返回boolean判断a是否大于150二、函数式接口:
接口中只有一个抽象方法的接口,称为“函数式接口”。 使用了 @FunctionalInterface 注解的接口,说明该接口必须是函数式接口
@FunctionalInterface public interface Comparator三、Lambda 表达式的基础语法: 1)无参数,无返回值{ int compare(T o1, T o2); } @FunctionalInterface public interface Runnable { public abstract void run(); }
() -> System.out.println()
public void test1(){ Runnable r1 = new Runnable() { @Override public void run() { System.out.println("匿名内部类实现接口"); } }; r1.run(); System.out.println("--------------------------------"); Runnable r2 = () -> System.out.println("Lambda表达式实现函数式接口"); r2.run(); }
匿名内部类实现接口 -------------------------------- Lambda表达式实现函数式接口2)有一个参数,无返回值
(s) -> System.out.println(s)
若参数列表只有一个参数时,小括号可以省略不写
若lambda体中只有一条语句,return 和 大括号都可以省略不写(有return就要写大括号)
public void test2(){ Consumercon1 = new Consumer () { @Override public void accept(String s) { System.out.println(s); } }; con1.accept("Hello!"); System.out.println("---------------------------------------"); Consumer con2 = s -> System.out.println(s); con2.accept("弱水三千,只取一瓢"); }
Hello! --------------------------------------- 弱水三千,只取一瓢3)两个以上的参数
有两个以上的参数,并且lambda体中有多条语句 (若lambda体中有多条语句,大括号要写)
@Test public void test3(){ Comparatorcom1 = new Comparator () { @Override public int compare(String o1, String o2) { return Integer.compare(o1.length(), o2.length()); } }; int n1 = com1.compare("mom", "dad"); System.out.println(n1); System.out.println("----------------------------------------"); Comparator com2 = (x, y) -> { //使用大括号 System.out.println("多条语句"); return Integer.compare(x.length(), y.length()); }; System.out.println(com2.compare("vdfvdv", "dger")); System.out.println("----------------------------------------"); Comparator com3 = (x,y) -> Integer.compare(x.length(),y.length()); System.out.println(com3.compare("dsffg","fsdfghg")); }
0 ---------------------------------------- 多条语句 1 ---------------------------------------- -1四、Java 内置四大核心函数式接口 Consumer< T >: 消费型接口
@Test public void test1() { shopping(50,money -> System.out.println("shopping花费了"+money+"元")); } public void shopping(double money,Consumerc) { c.accept(money); }
shopping花费了50.0元Supplier< T > : 供给型接口
- 返回类型为 T 的对象
- 包含方法:T get();
// 需求:生产整数并存入集合中 @Test public void test2() { ListnumList = getNumList(10,()-> (int)(Math.random() * 100)); for (int n : numList) { System.out.println(n); } } public List getNumList(int n, Supplier s) { List list = new ArrayList<>(); for (int i = 0; i < n; i++) { list.add(s.get()); } return list; }
50 66 60 39 86 39 80 95 76 92 //随机十位数Function< R,T > : 函数型接口
-
返回类型为 R 的对象
-
包含方 法:R apply(T t)
@Test public void test3() { Listl=map(Arrays.asList("lambda","in","action"),(String s)-> s.length()); System.out.println(l); } public List map(List list, Function f) { List list1 = new ArrayList<>(); for (T s : list) { list1.add(f.apply(s)); } return list1; }
[6, 2, 6]Predicate< T > 断定型接口
-
返回 boolean 值。
-
包含方法 boolean test(T t);
@Test public void test4() { Listlist1=filter(Arrays.asList("love","the","world"),(s)->s.length() > 3); System.out.println(list1); } public List filter(List str , Predicate pre) { List list=new ArrayList<>(); for (String s : str) { if (pre.test(s)) { list.add(s); } } return list; }
[love, world]
看不懂的话多看两遍就行了,慢慢来
五、方法引用当要传递给Lambda体的 *** 作,已经有实现的方法了,可以使用方法引用
方法引用:使用 *** 作符 “ : : ” 将方法名和对象或类的名字分隔开来。 如下三种主要使用情况:
- 对象 : : 实例方法
//对象的引用 :: 实例方法名 //T get(); //String getName() @Test public void test3(){ Employee e = new Employee("July", 18); Suppliers = () -> e.getName(); System.out.println(s.get()); System.out.println("------------------------------------"); Supplier s2 = e::getAge; System.out.println(s2.get()); }
July ------------------------------------ 18
- 类 : : 实例方法
//boolean test(T t, U u); //boolean equals(Object anObject) @Test public void test5(){ BiPredicatebp = (x, y) -> x.equals(y); System.out.println(bp.test("fsf", "fgd")); System.out.println("-----------------------------------------"); BiPredicate bp2 = String::equals; System.out.println(bp.test("fsf", "fsf")); } }
false ----------------------------------------- true
- 类 : : 静态方法
//类名 :: 静态方法名 //int compare(int x, int y); //int compare(T o1, T o2); @Test public void test4(){ Comparatorcom1 = (x, y) -> Integer.compare(x, y); System.out.println(com1.compare(3, 5)); System.out.println("------------------------------------------"); Comparator com2 = Integer::compare; System.out.println(com2.compare(6,4)); }
-1 ------------------------------------------ 1
第一步先判断Lambda方法体是否为一个方法,若是,则判断该方法与接口中抽象方法的返回值类型是否一致,若一致,则可以使用方法引用
注意:
1.方法引用的方法的参数列表与返回值类型必须与函数式接口中抽象方法的参数列表与返回值类型保持一致
2.返回值类型相同的情况下,函数式接口中抽象方法参数列表的第一个参数,是方法引用方法的调用者,并且第二个参数是需要引用方法的第二个参数(或无参数)时
如:public boolean equals(Object anObject);
Object .equals(anObject);
六、构造器引用ClassName::new
与函数式接口相结合,自动与函数式接口中方法兼容。 可以把构造器引用赋值给定义的方法,与构造器参数列表要与接口中抽 象方法的参数列表一致!
//T get(); @Test public void test6(){ Suppliersup = () -> new Employee(); System.out.println(sup.get()); System.out.println("--------------------------------"); Supplier sup2 = Employee::new; System.out.println(sup2.get()); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)