Java大家庭已经出到11版本了,我还在使用jdk7=-=,再不学就来不及了,所以赶紧学一下Java8的新特性。
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口
函数式接口在java.util.function路径下。
在这个包中,每一个接口都被@FunctionalInterface标注,表示这个类是一个函数式接口,主要用于编译级错误检查,加上该注解,当你写的接口不符合函数式接口定义的时候,编译器会报错。-- 摘录自菜鸟编程
这次我们简单粗暴一下,贴出测试代码,看下具体使用场景和用法吧
package com.example.demo;
import com.example.demo.test.Car;
import com.example.demo.test.PrintConsumer;
import org.junit.Test;
import java.util.Comparator;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.BinaryOperator;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.DoubleToIntFunction;
import java.util.function.Function;
/**
* @author JingQ at 2019/1/25
*/
public class JDK8FunctionInterfaceTest {
/**
* BiConsumer<T, U>,接收两个参数,不返回结果(void)
*
* 输出:(说明函数内修改对象引用的话同时会修改对象的值)
* 娃哈哈真好喝
* TEST
*/
@Test
public void biConsumerTest() {
BiConsumer<Car, String> biConsumer = (a, b) -> {
System.out.println(a.getName() + b);
a.setName("TEST");
};
Car car = new Car();
car.setName("娃哈哈");
biConsumer.accept(car, "真好喝");
System.out.println(car.getName());
}
/**
* BiFunction<T, U, R>, 接收两个参数<T, U>,返回R类型的结果
* 输出:
* 0 - 相等
*/
@Test
public void biFunctionTest() {
BiFunction<Integer, Integer, String> biFunction = (a, b) -> String.valueOf(a+b);
System.out.println(biFunction.apply(1, 2).compareTo("3"));
}
/**
* BinaryOperator<T> 用来接收两个T类型的参数,返回T类型的结果
*/
@Test
public void binaryOperatorTest() {
// 比较两者的最大值
BinaryOperator<Integer> binaryOperator1 = BinaryOperator.maxBy(Comparator.naturalOrder());
System.out.println(binaryOperator1.apply(1, 2));
// 比较两者的最小值
BinaryOperator<Integer> binaryOperator2 = BinaryOperator.minBy(Comparator.naturalOrder());
System.out.println(binaryOperator2.apply(3, 4));
// 相加
BinaryOperator<Integer> add = (n1, n2) -> n1 + n2;
System.out.println(add.apply(1, 3));
}
/**
* BiPredicate<T, U>,接收两个参数<T, U>,返回一个boolean类型结果
* 输出:
* false
*/
@Test
public void biPredicateTest() {
BiPredicate<Integer, Integer> biPredicate = (a, b) -> a.equals(b);
System.out.println(biPredicate.test(1, 3));
}
/**
* Boolean类型 提供者,用来获取一个Boolean值
* 如果只是用来返回true/false,感觉这个方法比较鸡肋;感觉可以使用statement,在返回结果前执行
*/
@Test
public void booleanSupplierTest() {
BooleanSupplier booleanSupplier = () -> {
System.out.println("Pre Action");
return Boolean.TRUE;
};
System.out.println(booleanSupplier.getAsBoolean());
}
/**
* Consumer<T>,接受一个输入参数,返回空类型void
* 还有一个andThen,可以用来实现责任链模式
*
* 输出:
* TEST
*
* NEXT TEST
* Pre
* End
*/
@Test
public void consumerTest() {
// 接受String类型的参数
Consumer<String> consumer = System.out::println;
consumer.accept("TEST");
//空格预定
System.out.println();
// 责任链模式,可以设定下一个consumer
// PrintConsumer.java
// public void accept(String s) {
// System.out.println("Pre");
// //xxx
// System.out.println("End");
// }
Consumer<String> nextConsumer = new PrintConsumer();
consumer.andThen(nextConsumer).accept("NEXT TEST");
}
/**
* DoubleToIntFunction 只有一个applyAsInt方法,接受double类型的参数,返回int类型的结果
*/
@Test
public void doubleToIntFunctionTest() {
DoubleToIntFunction doubleToIntFunction = a -> (int) a;
System.out.println(doubleToIntFunction.applyAsInt(10L));
}
/**
* Function<T, U>函数接口,接受T类型的参数,返回U类型的结果
*
* compose和andThen这两个方法的区别在于执行方法的顺序问题
*
* compose先执行后面函数,然后执行前面的函数;andThen先执行前面的函数,然后再执行后面的函数
*/
@Test
public void functionTest() {
// 方法引用,Integer[类名]::valueOf[方法名](这个是静态方法引用)
Function<String, Integer> function1 = Integer::valueOf;
System.out.println(function1.apply("1010"));
// 输出 1010
// andThen方法的入参类型为上一个方法的返回类型
Function<Integer, String> function2 = a -> {
System.out.println("Pre Action : ");
return String.valueOf(a) + "10";
};
System.out.println(function1.andThen(function2).apply("1010"));
//输出
//Pre Action :
//101010
// compose方法
Function<Integer, String> function3 = a -> {
System.out.println(a);
return a + "2020";
};
//compose先执行后面函数, 需要注意参数传递时调用的方法是否兼容,避免报错
System.out.println(function1.compose(function3).apply(10));
//输出
//10
//102020
}
}
复制代码