- 初识Lambda
- 一、Lambda 表达式结构:
- 二、函数式接口:
- 三、Lambda 表达式的基础语法:
- 1)无参数,无返回值
- 2)有一个参数,无返回值
- 3)两个以上的参数
- 四、Java 内置四大核心函数式接口
- **Consumer< T >: 消费型接口**
- **Supplier< T > : 供给型接口**
- Function< R,T > : 函数型接口
- Predicate< T > 断定型接口
- 五、方法引用
- 六、构造器引用
可以把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(){
Consumer con1 = 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(){
Comparator com1 = 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,Consumer c)
{
c.accept(money);
}
shopping花费了50.0元Supplier< T > : 供给型接口
- 返回类型为 T 的对象
- 包含方法:T get();
// 需求:生产整数并存入集合中
@Test
public void test2()
{
List numList = 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()
{
List l=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()
{
List list1=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);
Supplier s = () -> 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(){
BiPredicate bp = (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(){
Comparator com1 = (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(){
Supplier sup = () -> new Employee();
System.out.println(sup.get());
System.out.println("--------------------------------");
Supplier sup2 = Employee::new;
System.out.println(sup2.get());
}



