快速入门的小栗子,常用的创建线程
@Test
public void test1(){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("以前大家都这么写");
}
}).start();
//使用lambda表达式
new Thread(()->{
System.out.println("我是一个小栗子,现在可以这么写");
}).start();
}
那么简单,怎么用呢?
- 参数部分:参数类型能推断出来就不用写参数的类型,没有参数就用空(),只有一个参数可以省略()
- 方法体部分:多条语句用{}包裹,单条语句可以省略{},如果是单条return语句的话,return也可以省
//无参数无返回值
Runnable runnable1=()->{
System.out.println("hhh");
System.out.println("yingyingying")
};
//只有一个参数
Consumer<String> con2 = s -> System.out.println(s)
//两个参数,类型推断,省掉return,{}
Comparator<Integer> comparator = (o1,o2) -> o1.compareTo(o2);
还可以再简单点!方法引用!--Lambda表达式的语法糖
- 使用情景
- 当要传递给方法体的操作已经有实现的方法的时候,就可以使用
- 使用格式
- 类或对象::方法名
- 使用的三种情况(可以记为对象::静态方法不允许)
- 对象::非静态方法(实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的 方法的参数列表和返回值类型保持一致)
User user = new User(); Supplier<String> sup1 = () -> user.getName(); Supplier<String> sup=()->user::getName; PrintStream ps=System.out; Consumer<String> consumer = ps::println;- 类::静态方法(实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的 方法的参数列表和返回值类型保持一致)
Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2); Comparator<Integer> com1 = Integer::compare; Function<Double,Long> func1 = d -> Math.round(d); Function<Double,Long> func2 = Math::round;- 类::非静态方法(函数式接口方法的第一个参数是需要引用方法的调用者,并且第二 个参数是需要引用方法的参数(或无参数))
Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2); Comparator<String> com2 = String :: compareTo; BiPredicate<String,String> pre1 = (s1,s2) -> s1.equals(s2); BiPredicate<String,String> pre2 = String :: equals; Function<Employee,String> func1 = e -> e.getName(); Function<Employee,String> func2 = Employee::getName;
构造器引用 ClassName::new
- 和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致。抽象方法的返回值类型即为构造器所属的类的类
Supplier<Employee> sup1 = () -> new Employee();
Supplier<Employee> sup2 = Employee :: new;
Function<Integer,Employee> func1 = id -> new Employee(id);
Function<Integer,Employee> func2 = Employee :: new;
BiFunction<Integer,String,Employee> func1 = (id,name) -> new Employee(id,name);
BiFunction<Integer,String,Employee> func2 = Employee :: new;
数组引用 type[]::new
Function<Integer,String[]> func1 = length -> new String[length];
Function<Integer,String[]> func2 = String[] :: new;
String[] arr1 = func1.apply(5);
好方便啊!我可以自己定义吗?
当然啦!需要表明自己定义的接口是函数式接口,那么啥时函数式接口呢? 如果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口,需在上面添加@FunctionalInterface 注解。
//自己定义的函数式接口
@FunctionalInterface
public interface MyInterface {
void method1();
}
@Test
public void test3(){
MyInterface myInterface = ()-> System.out.println("hhh");
myInterface.method1();
}
系统内置的常用函数式接口
- 四大核心接口
| 函数式接口 | 参数类型 | 返回类型 | 用途 |
|---|---|---|---|
| Consumer | T | void | 对类型为T的对象应用操作,包含方法void accept(T t) |
| Supplier | 无 | T | 返回类型为T的对象,包含方法:T get() |
| Function<T, R> | T | R | 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t) |
| Predicate | T | boolean | 确定类型为T的对象是否满足某约束,并返回 boolean值。包含方法:boolean test(T t) |
- 其他接口
理解与感悟
方法引用本质上时Lambda表达式->Lambda表达式本质上是函数式接口的实例->函数式接口的实例就是对象->Java OOP思想!