JDK8新特性 Lombda表达式复习
自定义函数式接口——@FunctionalInterface作用
jdk自带的一些常用的一些接口Callable、Runnable、Comparator等在JDK8中都添加了@FunctionalInterface注解。
说明
- 该注解只能标记在"有且仅有一个抽象方法"的接口上。
- JDK8接口中的静态方法和默认方法,都不算是抽象方法。
- 接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
- 该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。
- 为了规范,建议给所有需要使用函数式编程的接口都加上注解。
解析
1、只有一个抽象方法的情况
@FunctionalInterface
public interface MyInterface {
int test(int i);
}
2、有多个方法,但只有一个抽象方法,其他方法有默认实现
@FunctionalInterface
public interface MyInterface {
int test(int i);
default int add(int a, int b) {
return a + b;
}
default void sum(int a, int b) {
System.out.println("sum:" + a + b);
}
}
使用
为了方便理解,我们使用一下,看看效果
public static void main(String[] args) {
// 使用lombda实现test方法
MyInterface myInterface = i -> i*2;
// 调用刚刚实现的方法
System.out.println(myInterface.test(22));
// 调用默认重写的方法
System.out.println(myInterface.add(10,20));
myInterface.sum(100,20);
}
结果
44
30
sum:10020
函数接口1—将接口用于方法参数
需求:新建一个类,传入余额。类中定义一个方法,方法参数为接口,自定义余额格式化信息。
自定义接口
@FunctionalInterface
public interface SecondInterface {
/**
* 格式化金额
*/
String format(int i);
}
格式化金额类
class MyMoney{
private final int money;
public MyMoney(int money) {
this.money = money;
}
public void printMoney(SecondInterface secondInterface){
System.out.println("我的存款:"+secondInterface.format(this.money));
}
}
使用:
public static void main(String[] args) {
MyMoney myMoney = new MyMoney(999999);
myMoney.printMoney(i -> new DecimalFormat("#,###").format(i));
}
结论:我们使用lombda不需要关心接口名称是什么,只要关心传入的参数是什么,想让参数变成什么类型。
函数接口2—jdk自带函数接口
接口 | 输入参数 | 返回类型 | 使用说明 |
---|---|---|---|
Predicate | T | boolean | 断言 |
Consumer | T | / | 消费一个数据 |
Function<T,R> | T | R | 输入T输出R的函数 |
Supplier | / | T | 提供一个数据 |
UnaryOperator | T | T | 一元函数(输入输出类型相同) |
BiFunction<T,U,R> | (T,U) | R | 两个输入的函数 |
BinaryOperator | (T,T) | T | 二元函数(输入输出类型相同) |
使用
public static void main(String[] args) {
// 断言
Predicate<Integer> predicate = i -> i > 0;
System.out.println(predicate.test(-1));
// 消费
Consumer<String> consumer = s -> System.out.println(s);
consumer.accept("张三");
// 输入T输出R
Function<Integer, String> function = i -> i >= 0 ? "正数" : "负数";
function.apply(7);
// 提供一个数据
Supplier<String> stringSupplier = () -> "测试";
System.out.println(stringSupplier.get());
// 一元函数
UnaryOperator<String> unaryOperator = s -> "处理后" + s;
System.out.println(unaryOperator.apply("Test"));
// 两个输入的函数
BiFunction<String,Boolean,Integer> biFunction = (s, b) -> {
// 如果b为true,返回0;如果s为test返回1,否则返回-1
if (b){
return 0;
}
if ("test".equals(s)){
return 1;
}
return -1;
};
System.out.println(biFunction.apply("test", false));
// 二元函数
BinaryOperator<String> binaryOperator = (s, s2) -> s+s2;
System.out.println(binaryOperator.apply("雷军", "666"));
}
结果
false
张三
测试
处理后Test
1
雷军666
方法引用 ::
方法引用符
::
先来简单体验一下
public static void main(String[] args) {
Consumer<String> consumer1 = s -> System.out.println(s);
consumer1.accept("张三");
Consumer<String> consumer2 = System.out::println;
consumer2.accept("张三");
}
静态方法的方法引用
类名::方法名
新建 dog
类
public class Dog {
private String name;
public Dog(String name) {
this.name = name;
}
public static void bark(Dog dog) {
System.out.println(dog.name + "叫了");
}
}
引用静态方法 “bark
”
public static void main(String[] args) {
Consumer<Dog> consumer = Dog::bark;
consumer.accept(new Dog("哮天犬"));
}
控制台输出:哮天犬叫了
非静态方法使用对象实例引用
改变 Dog
类中的 bark
方法
public class Dog {
private String name;
public Dog(String name) {
this.name = name;
}
public void bark(Dog dog) {
System.out.println(dog.name + "叫了");
}
}
使用:
public static void main(String[] args) {
Dog dog = new Dog("张三");
Consumer<Dog> consumer = dog::bark;
consumer.accept(dog);
}
控制台输出:张三叫了
无参构造方法的引用
public class Dog {
private String name;
// 无参构造
public Dog() {}
public void bark(Dog dog) {
System.out.println(dog.name + "叫了");
}
}
使用
public static void main(String[] args) {
Supplier<Dog> supplier = Dog::new;
Dog dog = supplier.get();
}
有参构造方法的引用
public class Dog {
private String name;
// 有参构造
public Dog(String name) {
this.name = name;
}
public void bark(Dog dog) {
System.out.println(dog.name + "叫了");
}
}
使用
public static void main(String[] args) {
// 接收string,输出Dog,jdk会自动找到有参构造
Function<String,Dog> function = Dog::new;
Dog dog = function.apply("张三");
dog.bark(dog);
}
控制台输出:张三叫了