Java函数式接口
发布日期:2021-05-07 14:43:52 浏览次数:22 分类:技术文章

本文共 8995 字,大约阅读时间需要 29 分钟。

目录


函数式接口概述【理解】

概念
有且仅有一个抽象方法的接口
如何检测一个接口是不是函数式接口
@FunctionalInterface
放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败
注意事项
我们自己定义函数式接口的时候,
@FunctionalInterface
是可选的,就算我不写这个注解,只要保证满足函数
式接口定义的条件,也照样是函数式接口。但是,建议加上该注解

函数式接口作为方法的参数【应用】

需求描述
定义一个类
(RunnableDemo)
,在类中提供两个方法
一个方法是:
startThread(Runnable r)
方法参数
Runnable
是一个函数式接口
一个方法是主方法,在主方法中调用
startThread
方法
代码演示
public class
RunnableDemo
{
public static
void
main
(
String
[]
args
) {
//
在主方法中调用
startThread
方法
//
匿名内部类的方式
startThread
(
new
Runnable
() {
@Override
public
void
run
() {
System
.
out
.
println
(
Thread
.
currentThread
().
getName
()
+
"
线程启动了
"
);
}
});
//Lambda
方式
startThread
(()
->
System
.
out
.
println
(
Thread
.
currentThread
().
getName
()
+
"
线
程启动了
"
));
}
private static
void
startThread
(
Runnable r
) {
new
Thread
(
r
).
start
();
}
}

函数式接口作为方法的返回值【应用】

需求描述
定义一个类
(ComparatorDemo)
,在类中提供两个方法
一个方法是:
Comparator getComparator()
方法返回值
Comparator
是一个函数式接口
一个方法是主方法,在主方法中调用
getComparator
方法
代码演示

常用函数式接口之Supplier【应用】

Supplier
接口
Supplier
接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的
get
方法就会生产
什么类型的数据供我们使用。
常用方法
只有一个无参的方法
public class
ComparatorDemo
{
public static
void
main
(
String
[]
args
) {
//
定义集合,存储字符串元素
ArrayList
<
String
>
array
=
new
ArrayList
<
String
>
();
array
.
add
(
"cccc"
);
array
.
add
(
"aa"
);
array
.
add
(
"b"
);
array
.
add
(
"ddd"
);
System
.
out
.
println
(
"
排序前:
"
+
array
);
Collections
.
sort
(
array
,
getComparator
());
System
.
out
.
println
(
"
排序后:
"
+
array
);
}
private static
Comparator
<
String
>
getComparator
() {
//
匿名内部类的方式实现
// return new Comparator<String>() {
// @Override
// public int compare(String s1, String s2) {
// return s1.length()-s2.length();
// }
// };
//Lambda
方式实现
return
(
s1
,
s2
)
->
s1
.
length
()
-
s2
.
length
();
}
}
方法名
说明
T get()
按照某种实现逻辑
(
Lambda
表达式实现
)
返回一个数据
代码演示

5 Supplier接口练习之获取最大值【应用】

案例需求
定义一个类
(SupplierTest)
,在类中提供两个方法
一个方法是:
int getMax(Supplier sup)
用于返回一个
int
数组中的最大值
一个方法是主方法,在主方法中调用
getMax
方法
示例代码
public class
SupplierDemo
{
public static
void
main
(
String
[]
args
) {
String
s
=
getString
(()
->
"
林青霞
"
);
System
.
out
.
println
(
s
);
Integer
i
=
getInteger
(()
->
30
);
System
.
out
.
println
(
i
);
}
//
定义一个方法,返回一个整数数据
private static
Integer
getInteger
(
Supplier
<
Integer
>
sup
) {
return
sup
.
get
();
}
//
定义一个方法,返回一个字符串数据
private static
String
getString
(
Supplier
<
String
>
sup
) {
return
sup
.
get
();
}
}
public class
SupplierTest
{
public static
void
main
(
String
[]
args
) {
//
定义一个
int
数组
int
[]
arr
=
{
19
,
50
,
28
,
37
,
46
};
int
maxValue
=
getMax
(()
->
{
int
max
=
arr
[
0
];
for
(
int
i
=
1
;
i
<
arr
.
length
;
i
++
) {
if
(
arr
[
i
]
>
max
) {
max
=
arr
[
i
];
}
}

常用函数式接口之Consumer【应用】

Consumer
接口
Consumer
接口也被称为消费型接口,它消费的数据的数据类型由泛型指定
方法名
说明
void accept(T t)
对给定的参数执行此操作
default Consumer andThen(Consumer
after)
返回一个组合的
Consumer
,依次执行此操作,然后执行
after
操作
常用方法
Consumer
:包含两个方法
代码演示
return
max
;
});
System
.
out
.
println
(
maxValue
);
}
//
返回一个
int
数组中的最大值
private static
int
getMax
(
Supplier
<
Integer
>
sup
) {
return
sup
.
get
();
}
}
public class
ConsumerDemo
{
public static
void
main
(
String
[]
args
) {
//
操作一
operatorString
(
"
林青霞
"
,
s
->
System
.
out
.
println
(
s
));
//
操作二
operatorString
(
"
林青霞
"
,
s
->
System
.
out
.
println
(
new
StringBuilder
(
s
).
reverse
().
toString
()));
System
.
out
.
println
(
"--------"
);
//
传入两个操作使用
andThen
完成
operatorString
(
"
林青霞
"
,
s
->
System
.
out
.
println
(
s
),
s
->
System
.
out
.
println
(
new
StringBuilder
(
s
).
reverse
().
toString
()));
}
//
定义一个方法,用不同的方式消费同一个字符串数据两次
private static
void
operatorString
(
String
name
,
Consumer
<
String
>
con1
,
Consumer
<
String
>
con2
) {
// con1.accept(name);
// con2.accept(name);
con1
.
andThen
(
con2
).
accept
(
name
);
}

7 Consumer接口练习之按要求打印信息【应用】

案例需求
String[] strArray = {"
林青霞
,30", "
张曼玉
,35", "
王祖贤
,33"};
字符串数组中有多条信息,请按照格式:
姓名:
XX,
年龄:
XX"
的格式将信息打印出来
要求:
把打印姓名的动作作为第一个
Consumer
接口的
Lambda
实例
把打印年龄的动作作为第二个
Consumer
接口的
Lambda
实例
将两个
Consumer
接口按照顺序组合到一起使用
示例代码

常用函数式接口之Predicate【应用】

Predicate
接口
Predicate
接口通常用于判断参数是否满足指定的条件
常用方法
//
定义一个方法,消费一个字符串数据
private static
void
operatorString
(
String
name
,
Consumer
<
String
>
con
) {
con
.
accept
(
name
);
}
}
public class
ConsumerTest
{
public static
void
main
(
String
[]
args
) {
String
[]
strArray
=
{
"
林青霞
,30"
,
"
张曼玉
,35"
,
"
王祖贤
,33"
};
printInfo
(
strArray
,
str
->
System
.
out
.
print
(
"
姓名:
"
+
str
.
split
(
","
)[
0
]),
str
->
System
.
out
.
println
(
",
年龄:
"
+
Integer
.
parseInt
(
str
.
split
(
","
)[
1
])));
}
private static
void
printInfo
(
String
[]
strArray
,
Consumer
<
String
>
con1
,
Consumer
<
String
>
con2
) {
for
(
String
str
:
strArray
) {
con1
.
andThen
(
con2
).
accept
(
str
);
}
}
}
方法名
说明
boolean test(T t)
对给定的参数进行判断
(
判断逻辑由
Lambda
表达式实现
)
,返回
一个布尔值
default Predicate negate()
返回一个逻辑的否定,对应逻辑非
default Predicate and(Predicate
other)
返回一个组合判断,对应短路与
default Predicate or(Predicate
other)
返回一个组合判断,对应短路或
代码演示
public class
PredicateDemo01
{
public static
void
main
(
String
[]
args
) {
boolean
b1
=
checkString
(
"hello"
,
s
->
s
.
length
()
>
8
);
System
.
out
.
println
(
b1
);
boolean
b2
=
checkString
(
"helloworld"
,
s
->
s
.
length
()
>
8
);
System
.
out
.
println
(
b2
);
}
//
判断给定的字符串是否满足要求
private static
boolean
checkString
(
String
s
,
Predicate
<
String
>
pre
) {
// return !pre.test(s);
return
pre
.
negate
().
test
(
s
);
}
}
public class
PredicateDemo02
{
public static
void
main
(
String
[]
args
) {
boolean
b1
=
checkString
(
"hello"
,
s
->
s
.
length
()
>
8
);
System
.
out
.
println
(
b1
);
boolean
b2
=
checkString
(
"helloworld"
,
s
->
s
.
length
()
>
8
);
System
.
out
.
println
(
b2
);
boolean
b3
=
checkString
(
"hello"
,
s
->
s
.
length
()
>
8
,
s
->
s
.
length
()
<
15
);
System
.
out
.
println
(
b3
);
boolean
b4
=
checkString
(
"helloworld"
,
s
->
s
.
length
()
>
8
,
s
->
s
.
length
()
<
15
);
System
.
out
.
println
(
b4
);
}
//
同一个字符串给出两个不同的判断条件,最后把这两个判断的结果做逻辑与运算的结果作为最终的结果
private static
boolean
checkString
(
String
s
,
Predicate
<
String
>
pre1
,
Predicate
<
String
>
pre2
) {
return
pre1
.
or
(
pre2
).
test
(
s
);
}

9 Predicate接口练习之筛选满足条件数据【应用】

练习描述
String[] strArray = {"
林青霞
,30", "
柳岩
,34", "
张曼玉
,35", "
貂蝉
,31", "
王祖贤
,33"};
字符串数组中有多条信息,请通过
Predicate
接口的拼装将符合要求的字符串筛选到集合
ArrayList
中,并
遍历
ArrayList
集合
同时满足如下要求:姓名长度大于
2
;年龄大于
33
分析
有两个判断条件
,
所以需要使用两个
Predicate
接口
,
对条件进行判断
必须同时满足两个条件
,
所以可以使用
and
方法连接两个判断条件
示例代码
//
判断给定的字符串是否满足要求
private static
boolean
checkString
(
String
s
,
Predicate
<
String
>
pre
) {
return
pre
.
test
(
s
);
}
}
public class
PredicateTest
{
public static
void
main
(
String
[]
args
) {
String
[]
strArray
=
{
"
林青霞
,30"
,
"
柳岩
,34"
,
"
张曼玉
,35"
,
"
貂蝉
,31"
,
"
王祖
,33"
};
ArrayList
<
String
>
array
=
myFilter
(
strArray
,
s
->
s
.
split
(
","
)[
0
].
length
()
>
2
,
s
->
Integer
.
parseInt
(
s
.
split
(
","
)[
1
])
>
33
);
for
(
String
str
:
array
) {
System
.
out
.
println
(
str
);
}
}
//
通过
Predicate
接口的拼装将符合要求的字符串筛选到集合
ArrayList
private static
ArrayList
<
String
>
myFilter
(
String
[]
strArray
,
Predicate
<
String
>
pre1
,
Predicate
<
String
>
pre2
) {
//
定义一个集合
ArrayList
<
String
>
array
=
new
ArrayList
<
String
>
();
//
遍历数组
for
(
String
str
:
strArray
) {
if
(
pre1
.
and
(
pre2
).
test
(
str
)) {
array
.
add
(
str
);
}
}
return
array
;
}
}

10 常用函数式接口之Function【应用】

Function
接口
Function<T,R>
接口通常用于对参数进行处理,转换
(
处理逻辑由
Lambda
表达式实现
)
,然后返回一个新的值
方法名
说明
R apply(T t)
将此函数应用于给定的参数
default Function
andThen(Function after)
返回一个组合函数,首先将该函数应用于输入,然后将
after
数应用于结果
常用方法
代码演示
public class
FunctionDemo
{
public static
void
main
(
String
[]
args
) {
//
操作一
convert
(
"100"
,
s
->
Integer
.
parseInt
(
s
));
//
操作二
convert
(
100
,
i
->
String
.
valueOf
(
i
+
566
));
//
使用
andThen
的方式连续执行两个操作
convert
(
"100"
,
s
->
Integer
.
parseInt
(
s
),
i
->
String
.
valueOf
(
i
+
566
));
}
//
定义一个方法,把一个字符串转换
int
类型,在控制台输出
private static
void
convert
(
String
s
,
Function
<
String
,
Integer
>
fun
) {
// Integer i = fun.apply(s);
int
i
=
fun
.
apply
(
s
);
System
.
out
.
println
(
i
);
}
//
定义一个方法,把一个
int
类型的数据加上一个整数之后,转为字符串在控制台输出
private static
void
convert
(
int
i
,
Function
<
Integer
,
String
>
fun
) {
String
s
=
fun
.
apply
(
i
);
System
.
out
.
println
(
s
);
}
//
定义一个方法,把一个字符串转换
int
类型,把
int
类型的数据加上一个整数之后,转为字符串在控制台
输出
private static
void
convert
(
String
s
,
Function
<
String
,
Integer
>
fun1
,
Function
<
Integer
,
String
>
fun2
) {
String
ss
=
fun1
.
andThen
(
fun2
).
apply
(
s
);
System
.
out
.
println
(
ss
);
}
}

11 Function接口练习之按照指定要求操作数据【应用】

练习描述
String s = "
林青霞
,30";
请按照我指定的要求进行操作:
1:
将字符串截取得到数字年龄部分
2:
将上一步的年龄字符串转换成为
int
类型的数据
3:
将上一步的
int
数据加
70
,得到一个
int
结果,在控制台输出
请通过
Function
接口来实现函数拼接
示例代码
public class
FunctionTest
{
public static
void
main
(
String
[]
args
) {
String
s
=
"
林青霞
,30"
;
convert
(
s
,
ss
->
ss
.
split
(
","
)[
1
],
Integer
::
parseInt
,
i
->
i
+
70
);
}
private static
void
convert
(
String
s
,
Function
<
String
,
String
>
fun1
,
Function
<
String
,
Integer
>
fun2
,
Function
<
Integer
,
Integer
>
fun3
) {
int
i
=
fun1
.
andThen
(
fun2
).
andThen
(
fun3
).
apply
(
s
);
System
.
out
.
println
(
i
);
}
}
上一篇:Java流Strem
下一篇:Java方法四种引用

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2025年04月10日 04时05分05秒