- Lambda
- 接口中新特性
- 方法引用
- 理解
简单 看不懂
- 格式:
- 格式说明:
- Lambda的本质是什么?
匿名方法,就是没有名字的方法
- Lambda主要解决的问题是什么?
简化匿名内部类写法的
定义方法的格式:
- 练习一(无参无返回值抽象方法的练习)
/*
Lambda表达式的格式:(形式参数) -> {代码块}
练习1:
1:定义一个接口(Eatable),里面定义一个抽象方法:void eat();
2:定义一个测试类(EatableDemo),在测试类中提供两个方法
一个方法是:useEatable(Eatable e)
一个方法是主方法,在主方法中调用useEatable方法
*/
public class EatableDemo {
public static void main(String[] args) {
//在主方法中调用useEatable方法
Eatable e = new EatableImpl();
useEatable(e);
//匿名内部类
useEatable(new Eatable() {
@Override
public void eat() {
System.out.println("一天一苹果,医生远离我");
}
});
//Lambda表达式
useEatable(() -> {
System.out.println("一天一苹果,医生远离我");
});
}
/*
接口作为方法的参数:
传递的是该接口的实现类的对象
1. 传统方式 -- 定义一个类,实现该接口
2. 匿名内部类,简化第一种方式
3. 使用Lambda表达式 ,简化第二种方式
*/
private static void useEatable(Eatable e) {
e.eat();
}
}
/*
接口中只有一个抽象方法,该接口称之为函数式接口
*/
public interface Eatable {
void eat();
}
- 练习二(有参无返回值抽象方法的练习)
/*
Lambda表达式的格式:(形式参数) -> {代码块}
练习2:
1:定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s);
2:定义一个测试类(FlyableDemo),在测试类中提供两个方法
一个方法是:useFlyable(Flyable f)
一个方法是主方法,在主方法中调用useFlyable方法
*/
public class FlyableDemo {
public static void main(String[] args) {
//在主方法中调用useFlyable方法
//匿名内部类
useFlyable(new Flyable() {
@Override
public void fly(String s) {
System.out.println(s);
System.out.println("飞机自驾游");
}
});
System.out.println("--------");
//Lambda
useFlyable((String s) -> {
System.out.println(s);
});
}
private static void useFlyable(/*String s,*/ Flyable f) {
f.fly("风和日丽,晴空万里");
}
}
public interface Flyable {
void fly(String s);
}
- 练习三(有参有返回值抽象方法的练习)
/*
Lambda表达式的格式:(形式参数) -> {代码块}
练习3:
1:定义一个接口(Addable),里面定义一个抽象方法:int add(int x,int y);
2:定义一个测试类(AddableDemo),在测试类中提供两个方法
一个方法是:useAddable(Addable a)
一个方法是主方法,在主方法中调用useAddable方法
*/
public class AddableDemo {
public static void main(String[] args) {
//在主方法中调用useAddable方法
useAddable((int x,int y) -> {
return x + y;
// return x - y;
});
}
private static void useAddable(Addable a) {
int sum = a.add(10, 20);
System.out.println(sum);
}
}
public interface Addable {
int add(int x, int y);
}
- Lambda表达式的省略模式
省略的思路:
省略的规则:
- Lambda表达式的注意事项
必须是一个接口 ,接口中有且仅有一个抽象方法必须有上下文,否则推断不出来的
- Lambda表达式和匿名内部类的区别
- 接口中可以定义的内容有?
- 接口中默认方法
总结:
格式:
加入默认方法, 可以解决什么样的问题?
- 接口中静态方法
格式:
public static 返回值类型 方法名(参数类别){}
注意事项:
使用的格式:
- 接口中私有方法
普通私有方法:
静态私有方法:
注意事项:
接口中私有方法的作用:
- 体验方法引用
- 方法引用语法
- 引用类方法
总结:
案例代码:
/*
练习:
1:定义一个接口(Converter),里面定义一个抽象方法:
int convert(String s);
2:定义一个测试类(ConverterDemo),在测试类中提供两个方法
一个方法是:useConverter(Converter c)
一个方法是主方法,在主方法中调用useConverter方法
*/
public class ConverterDemo {
public static void main(String[] args) {
//在主方法中调用useConverter方法
// 使用匿名内部类
useConverter(new Converter() {
@Override
public int convert(String s) {
return Integer.parseInt(s);
}
});
// useConverter((String s) -> {
// return Integer.parseInt(s);
// });
useConverter(s -> Integer.parseInt(s));
//引用类方法
useConverter(Integer::parseInt);
//Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数
}
private static void useConverter(Converter c) {
int number = c.convert("666");
System.out.println(number);
}
}
public interface Converter {
// 将字符串转换为整数int
int convert(String s);
}
- 引用对象的实例方法
总结:
案例代码:
public class PrinterDemo {
public static void main(String[] args) {
//在主方法中调用usePrinter方法
// usePrinter((String s) -> {
//// String result = s.toUpperCase();
//// System.out.println(result);
// System.out.println(s.toUpperCase());
// });
usePrinter(s -> System.out.println(s.toLowerCase()));
//引用对象的实例方法
PrintString ps = new PrintString();
usePrinter(ps::printUpper);
//Lambda表达式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数
}
private static void usePrinter(Printer p) {
p.printUpperCase("HelloWorld");
}
}
public class PrintString {
//把字符串参数变成大写的数据,然后在控制台输出
public void printUpper(String s) {
String result = s.toUpperCase();
System.out.println(result);
}
}
public interface Printer {
void printUpperCase(String s);
}
- 引用类的实例方法
public class MyStringDemo {
public static void main(String[] args) {
//在主方法中调用useMyString方法
// useMyString((String s,int x,int y) -> {
// return s.substring(x,y);
// });
useMyString((s,x,y) -> s.substring(x,y));
//引用类的实例方法
useMyString(String::substring);
//Lambda表达式被类的实例方法替代的时候
//第一个参数作为调用者
//后面的参数全部传递给该方法作为参数
}
private static void useMyString(MyString my) {
String s = my.mySubString("HelloWorld", 2, 5);
System.out.println(s);
}
}
public interface MyString {
String mySubString(String s, int x, int y);
}
- 引用构造器
public class StudentDemo {
public static void main(String[] args) {
//在主方法中调用useStudentBuilder方法
// useStudentBuilder((String name,int age) -> {
//// Student s = new Student(name,age);
//// return s;
// return new Student(name,age);
// });
useStudentBuilder((name,age) -> new Student(name,age));
//引用构造器
useStudentBuilder(Student::new);
//Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数
}
private static void useStudentBuilder(StudentBuilder sb) {
Student s = sb.build("林青霞", 30);
System.out.println(s.getName() + "," + s.getAge());
}
}
public class Student {
private String name;
private int age;
}
public interface StudentBuilder {
Student build(String name, int age);
}
//引用构造器
useStudentBuilder(Student::new);
//Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数
}
private static void useStudentBuilder(StudentBuilder sb) {
Student s = sb.build("林青霞", 30);
System.out.println(s.getName() + "," + s.getAge());
}
}
public class Student {
private String name;
private int age;
}
public interface StudentBuilder {
Student build(String name, int age);
}