Java8常用的函数式接口

[toc]

常用函数式接口

仅含有一个抽象方法的接口(不是只有一个方法)

该接口常与Lambda表达式相联系

Lambda表达式延迟加载,可避免性能浪费

1、函数型接口-Function

有参数且需要有返回值

java.util.function.Function接口用来根据一个数据类型得到另一个数据类型,前者称为前置条件,后者称为后置条件。

抽象方法:apply,R apply,根据类型T的参数获取R型的结果,返回的是另一个类型的值。

@Slf4j
public class FunctionTest {
public static void main(String[] args) {
String str = "2020";
Integer num = convert(str ,(String str1)->{
return Integer.parseInt(str1);
});
log.info("返回结果为:{}", num);
}
public static Integer convert(String str, Function function){
return function.apply(str);
}
}

2、供给型接口-Supplier

无参数,指定返回值类型,经常用于只注重过程的代码

java.util.function.Supplier 接口仅包含一个无参的方法:T get(),用来获取一个泛型参数指定类型的对象数据。由于这是一个函数式接口,也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据

Supplier<>接口被称为生产型接口,指定接口的泛型是什么类型,那么接口的get方法就会生产什么类型的数据,有返回值

@Slf4j
public class SupplierTest {
public static void main(String[] args) {
Integer[] arrays = new Integer[]{1,2,3,4,5,6,7,8,9};
//调用getMax方法,使用Lambda表达式简写
Integer maxInt = getMax(() -> {
Integer maxInt1 = arrays[0];
for (Integer i : arrays){
if (maxInt1 < i){
maxInt1 = i;
}
}
return maxInt1;
});
log.info("最大的值为:{}", maxInt);
}
public static Integer getMax(Supplier supplier){
return supplier.get();
}
}
//或者用以下的写法
@Slf4j
public class SupplierTest {
public static void main(String[] args) {
Integer[] arrays = new Integer[]{1,2,3,4,5,6,7,8,9};
Integer maxInt = getMax(new Supplier() {
@Override
public Integer get() {
Integer maxInt1 = arrays[0];
for (Integer i : arrays){
if (maxInt1 < i){
maxInt1 = i;
}
}
return maxInt1;
}
});
log.info("最大的值为{}", maxInt);
}
public static Integer getMax(Supplier supplier){
return supplier.get();
}
}

3、消费型接口-Consumer

不需要返回值,有参数,经常用于迭代

java.util.function.Consumer接口正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定

Consumer接口中包含抽象方法void accept(T t),意为消费一个指定泛型的数据,无返回值

@Slf4j
public class ConsumerTest {
public static void print(Integer year, Consumer age){
//accept方法接受的数据可以输出、计算等
age.accept(year);
}
public static void method(String[] strArr, Consumer con1, Consumer con2){
con1.andThen(con2).accept(strArr);
}
/**
* 另一种消费写法
* @param strArr
* @param con1
* @param con2
*/
public static void consumption(String[] strArr, Consumer con1, Consumer con2){
for (String message : strArr){
con1.andThen(con2).accept(message);
}
}
public static void main(String[] args) {
//消费方式:直接输出
print((2020), (year) -> log.info("出生年月为:{}", year));
print((2020), (year)->{
String yearStr = year.toString();
String resultYear = new StringBuilder(yearStr).reverse().toString();
log.info("反转的字符串为:{}", resultYear);
});
//定义一个字符串数组
String[] person ={"憨憨,男","巴适,女"};
method(person, (str)->{
for (String name: str){
log.info("第一位用户姓名:{}", name.split(",")[0]);
}
},(str)->{
for (String name: str){
log.info("第二位用户性别:{}", name.split(",")[1]);
}
});
//另一种消费写法
consumption(person, (message)->{
log.info("第二种写法中获取姓名:{}", message.split(",")[0]);
},(message)->{
log.info("第二种写法中获取性别:{}", message.split(",")[1]);
});
}
}

4、判断型接口-Predicate

返回 true/false 经常用于判断

对某种数据类型的数据进行判断,从而得到一个boolean值的结果,这时可以使用java.util.function.predicate接口

Predicate接口中含有一个抽象方法:boolean test(T t)。用于条件判断的场景,返回值为布尔值

@Slf4j
public class PredicateTest {
public static void main(String[] args) {
List list = Arrays.asList(1,2,3,4,5,6,7,8,9);
// Predicate predicate = n -> true
// n 是一个参数传递到 Predicate 接口的 test 方法
// n 如果存在则 test 方法返回 true
log.info("输出所有数据:");
eval(list, n -> true);
log.info("所有偶数:");
eval(list, n -> n % 2 ==0);
//输出结果:2 4 6 8
log.info("所有奇数:");
eval(list, n -> n % 2 != 0);
//输出结果为:1 3 5 7 9
log.info("大于5的数");
eval(list, n -> n > 5);
//输出结果 6 7 8 9
}
public static void eval(List list, Predicate predicate){
for (Integer n : list){
if ( predicate.test(n) ){
log.info("输出的结果为:{}", n);
}
}
}
}