Java函数式接口

简介: Java函数式接口

1 函数式接口概述【理解】

概念

有且仅有一个抽象方法的接口

如何检测一个接口是不是函数式接口

@FunctionalInterface

放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败

注意事项

我们自己定义函数式接口的时候, @FunctionalInterface 是可选的,就算我不写这个注解,只要保证满足函数

式接口定义的条件,也照样是函数式接口。但是,建议加上该注解

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

需求描述

定义一个类 (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 ();
}
}

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

需求描述

定义一个类 (ComparatorDemo) ,在类中提供两个方法

一个方法是: Comparator getComparator() 方法返回值 Comparator 是一个函数式接口

一个方法是主方法,在主方法中调用 getComparator 方法

代码演示

4 常用函数式接口之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 ];
}
}

6 常用函数式接口之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 接口按照顺序组合到一起使用

示例代码

8 常用函数式接口之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 );
}
}


目录
相关文章
|
22天前
|
设计模式 Java
Java基础—笔记—多态、final、抽象类、接口篇
该文介绍了编程中的多态、final和抽象类、接口相关概念。多态允许子类重写父类方法,通过父类引用调用子类方法,实现解耦和提高代码灵活性,但也可能导致无法使用子类特有功能,需通过强制类型转换解决。final用于修饰不可变的类、方法或变量,防止继承、重写和多次赋值。抽象类是一种包含抽象方法的类,用于强制子类重写特定方法,实现多态,适用于模板方法设计模式,解决代码重复问题。
17 0
|
22天前
|
Java
Java基础—笔记—接口篇
接口是Java中的一个抽象概念,用于创建数据结构,类似于更纯粹的抽象类。定义包括常量(默认public static final)和抽象方法(默认public abstract)。接口通过子类实现,如`public class 子类 implements 接口1, 接口2...`。JDK8后增加了默认方法(通过子类对象调用)和静态方法(通过接口名调用)。JDK9引入了私有方法,仅在接口默认方法中调用。目的是在不修改子类的情况下扩展功能。一个类可以继承一个父类并实现多个接口,一个接口可继承多个接口。
11 0
|
2天前
|
存储 Java
java IO接口(Input)用法
【5月更文挑战第1天】Java的`java.io`包包含多种输入输出类。此示例展示了如何使用`FileInputStream`从`input.txt`读取数据。首先创建`FileInputStream`对象,接着创建一个字节数组存储读取的数据,调用`read()`方法将文件内容填充至数组。然后将字节数组转换为字符串并打印,最后关闭输入流。注意,`InputStream`是抽象类,此处使用其子类`FileInputStream`。其他子类如`ByteArrayInputStream`、`ObjectInputStream`和`BufferedInputStream`各有特定用途。
9 2
|
2天前
|
NoSQL Java API
java一行代码实现RESTFul接口
Spring Data REST是构建在Spring Data之上的库,可自动将repository转换为REST服务,支持JPA、MongoDB、Neo4j、GemFire和Cassandra。无需手动创建Service和Controller层。要开始,需配置JPA数据源,创建实体类和Repository接口。快速实现REST接口,只需引入spring-boot-starter-data-rest Maven依赖,并在Repository接口上添加@RepositoryRestResource注解。
|
3天前
|
Java 程序员 数据格式
关于Java抽象类和接口的总结和一点个人的看法
关于Java抽象类和接口的总结和一点个人的看法
|
8天前
|
存储 安全 Java
[Java基础面试题] Map 接口相关
[Java基础面试题] Map 接口相关
|
9天前
|
Java
一文搞清楚Java中的包、类、接口
包、类、接口、方法、变量、参数、代码块,这些都是构成Java程序的核心部分,即便最简单的一段代码里都至少要包含里面的三四个内容,这两天花点时间梳理了一下,理解又深刻了几分。
31 10
|
14天前
|
Java 开发者
探索 Java 的函数式接口和 Lambda 表达式
【4月更文挑战第19天】Java 中的函数式接口和 Lambda 表达式提供了简洁、灵活的编程方式。函数式接口有且仅有一个抽象方法,用于与 Lambda(一种匿名函数语法)配合,简化代码并增强可读性。Lambda 表达式的优点在于其简洁性和灵活性,常用于事件处理、过滤和排序等场景。使用时注意兼容性和变量作用域,它们能提高代码效率和可维护性。
|
14天前
|
Java
Java接口中可以定义哪些方法?
【4月更文挑战第13天】
14 0
Java接口中可以定义哪些方法?
|
14天前
|
Java API
什么是Java函数式接口?
【4月更文挑战第13天】
15 0
什么是Java函数式接口?