文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

结合Java所有特性,系统全面讲解函数式接口及应用

2024-12-01 02:15

关注

掌握内容

函数式接口

函数式接口就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,是Lambda表达式的实现前提,可以使用@FunctionalInterface注解修饰

函数式接口意义

Java一直倡导面向对象,随着Python、Scala等语言的兴起和新技术的挑战,Java必须调整来支持更加广泛的技术要求,所以Java不单单OOP【面向对象编程】同样支持OOF【面向函数编程】。

以往需要通过匿名内部类实现,现在都可以通过Lambda实现,其实Lambda表达式可以看做是一个函数式接口的实例。

JDK内置函数式接口

注:不需要掌握,不需要掌握!我看网上很多资料都只写了四个内置接口,比较局限,这里对JDK内置接口做一个全面的说明,只需要知道有这么多内置接口,并不是只有四个就可以了。

JDK8新增函数式接口:

JDK8新推出的函数式接口在java.util.function包下

作用如下:

函数式接口

参数类型

返回类型

用途

Consumer 消费型接口

T

void

对类型为T的对象应用操作,包含方法:void accept(T t)

Supplier 供给型接口

T

返回类型为T的对象,包含方法:T get()

Function函数型接口

T

R

对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t)

Predicate断定型接口

T

boolean

确定类型为T的对象是否满足某约束,并返回boolean 值。包含方法:boolean test(T t)

BiFunction

T, U

R

对类型为T,U参数应用操作,返回R类型的结果。包含方法为:Rapply(T t,U u)

UnaryOperator(Function子接口)

T

T

对类型为T的对象进行一元运算,并返回T类型的结果。包含方法为:Tapply(T t);

BinaryOperator(BiFunction子接口)

T,T

T

对类型为T的对象进行二元运算,并返回T类型的结果。包含方法为:Tapply(T t1,T t2);

BiConsumer

T,U

void

对类型为T,U参数应用操作。包含方法为:voidaccept(Tt,Uu)

BiPredicate

T,U

boolean

包含方法为:booleantest(Tt,Uu)

ToIntFunction

T

int

计算int值的函数

ToLongFunction

T

long

计算long值的函数

ToDoubleFunction

T

double

计算double值的函数

IntFunction

int

R

参数为int类型的函数

LongFunction

long

R

参数为long类型的函数

DoubleFunction

double

R

参数为double类型的函数

JDK8之前的函数式接口:

JDK8之前也存在函数式接口,在JDK8升级之后这些接口头部都加上了@FunctionalInterface修饰,如下:

函数式接口使用

在上篇中我们已经使用过Runnable、Consumer、Supplier、Comparator等接口,这里我们再使用Function和Predicate接口,其他接口如果用到了可以照葫芦画瓢即可!

Function接口

接口定义如下:

小贴士:接口中有且仅有一个抽象方法的接口就是一个函数式接口,和默认实现以及静态方法无关。

package java.util.function;

import java.util.Objects;


R apply(T t);


default Function compose(Function before){
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}


default Function andThen(Function after){
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}


static Function identity(){
return t -> t;
}
}

接口特点:有一个输入参数和一个输出参数,也就是一进一出,如果你有需求是传入一个参数并返回一个参数的需求可以使用该接口实现。

需求:

实现一个字符串转换功能,将输入的英文字符都转换为大写返回。

分析:

输入和输出数据都是字符串所有泛型类型均为String。

调用 apply方法进行计算之后接收返回值。

代码实现:

public class FunctionMain {
public static void main(String[] args) {

// 1、原始匿名内部类写法
Function<String, String> function1 = new Function<String, String>() {
@Override
public String apply(String inputStr) {
// 转换为大写
return inputStr.toUpperCase();
}
};

String result = function1.apply("Just give me a chance to start!");
System.out.println(result);

// 2、Lambda表达式写法
Function<String,String> function2 = inputStr -> inputStr.toUpperCase();
String lambdaResult = function2.apply("Lambda really smells good!");
System.out.println(lambdaResult);

}
}

Predicate接口

接口定义:

该接口也存在默认实现和静态方法,但是只有一个抽象方法,所以也是一个函数式接口。

package java.util.function;

import java.util.Objects;


@FunctionalInterface
public interface Predicate<T> {


boolean test(T t);


default Predicate<T> and(Predicate<? super T> other){
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}


default Predicate<T> negate(){
return (t) -> !test(t);
}

default Predicate<T> or(Predicate<? super T> other){
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}


static <T> Predicate<T> isEqual(Object targetRef){
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}

接口特点:该接口根据传入数据通过计算之后返回true或者false,如果你想要做单个参数的判断可以使用该接口。

小贴士:Java中有两个Predicate类,不要导错包,认准java.util.function包,当然自定义的类也不要起这个名字,【有许多初学者喜欢起同名的类】。

需求:判断输入的数据是否大于0。

分析:

代码实现:

public class PredicateMain {
public static void main(String[] args){

// 1、原始实现方式
Predicate predicate1 = new Predicate<Integer>() {
@Override
public boolean test(Integer num){
return num > 0;
}
};
// 调用test方法
boolean result = predicate1.test(1024);
System.out.println(result);

// 2、Lambda表达式实现
Predicate<Integer> predicate2 = num -> num > 0;
// 调用test方法
boolean lambdaResult = predicate2.test(-1024);
System.out.println(lambdaResult);

}
}

小贴士:这些默认方法的接口,使用时不要调用错方法就行!

自定义函数式接口

分析:

函数式接口就是有且仅有一个抽象方法,默认实现和静态方法不影响它是一个函数式接口【JDK8支持接口有默认方法和静态方法】。

接口,定义抽象即可,所以我这里都使用泛型,可以根据自己的需求定义,如果需求要限制类型也可以直接定义成具体的类型。

接口定义:

package com.stt.function.myfunction;


@FunctionalInterface
public interface SttFunction<T,R,V> {


V calc(T t,R r);

}

接口使用:

package com.stt.function.myfunction;

public class SttFunctionMain {

public static void main(String[] args) {
// 1、原始方式,匿名内部类实现
SttFunction<Integer, Integer, Integer> sttFunction1 = new SttFunction<Integer, Integer, Integer>() {
@Override
public Integer calc(Integer num1, Integer num2) {
return num1 * num2;
}
};
Integer result = sttFunction1.calc(2, 2);
System.out.println(result);

// 2、Lambda表达式调用
SttFunction<Integer,Integer,Integer> sttFunction = (num1,num2) -> num1 + num2;;

Integer lambdaResult = sttFunction.calc(1023, 1);

System.out.println(lambdaResult);

}
}

Lambda表达式就是香。

包含默认实现的函数式接口:

包含默认方法和静态方法并不影响它是一个函数式接口。

package com.stt.function.myfunction;


@FunctionalInterface
public interface SttFunction<T,R,V> {


V calc(T t,R r);

default void defaultMethod(){
System.out.println("也不知道实现点什么,反正JDK8之后可以有默认实现!");
}

static void staticMethod(){
System.out.println("同样不知道写点什么,反正JDK8之后可以有静态方法!");
}
}

有多个抽象方法:

有两个以上抽象方法就不再是一个函数式接口,所以@FunctionalInterface注解报错,该注解可以用来检验接口是否为一个函数式接口。

@FunctionalInterface注解

Java 8中专门为函数式接口引入了一个新的注解:@FunctionalInterface 。该注解放在接口上,表示此接口是一个函数式接口。并且提示编译器去检查接口是否仅包含一个抽象方法,即,是否符合函数式编程的定义。

小贴士:如果自定义一个符合规范的函数式接口,也可以不加@FunctionalInterface注解,此注解只是起到一个提示编译器进行规范检查的作用

总结

文章出自:​​添甄​​,如有转载本文请联系【添甄】今日头条号。

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯