Java SE入门及基础(54)& 函数式接口

目录

[1. 什么是函数式接口](#1. 什么是函数式接口)

函数式接口

示例

示例

[2. 函数式编程](#2. 函数式编程)

示例

[3. Lambda 表达式延迟执行](#3. Lambda 表达式延迟执行)

应用场景

示例

[4. Consumer 接口](#4. Consumer 接口)

解释说明

示例

[5. BiConsumer 接口](#5. BiConsumer 接口)

解释说明

示例

[6. Predicate 接口](#6. Predicate 接口)

解释说明

示例

练习

[7. Function 接口](#7. Function 接口)

解释说明

示例

练习


**1.**什么是函数式接口

函数式接口

A functional interface is any interface that contains only one abstract method. (A functional interface may contain one or more default methods or static methods.) Because a functional interface contains only one abstract method, you can omit the name of that method when you implement it.
函数式接口是仅包含一种抽象方法的任何接口。 (一个函数式接口可能包含一个或多个默认方法或静态方法。)由于一个函数式接口仅包含一个抽象方法,因此在实现该方法时可以省略该方法的名称。

示例

public interface Hello {
void sayHello ( String name );
static void show (){}
default void print (){}
private void test (){}
}
JDK8 专门为函数式接口提供了一个注解标识 @FunctionalInterface ,该注解只能使用在接口类型的定义上,表明这是一个函数式接口, 编译器在编译时就是会对该接口进行检测:接口中是否只有一个抽 象接口方法。如果有多个抽象接口方法或者一个抽象接口方法也没有,则将报编译错误

示例

@FunctionalInterface
public interface Hello {
void sayHello ( String name );
static void show (){}
default void print (){}
private void test (){}
}
注意: 如果接口类型上没有 @FunctionalInterface 注解,但接口中只有一个抽象方法,这个接口也 是函数式接口。这与 @Override 注解一样,即使方法上面没有写,同样是属于方法重写

**2.**函数式编程

函数式编程是一种编程方式,在 Java 中,简单来说就是一个变量能够存储一个函数。而能够实现这种赋值操作的只有 Lambda 表达式

示例

@FunctionalInterface
public interface Hello {
void sayHello ( String name );
static void show (){}
default void print (){}
// private void test(){}
}
package com . wq . functional ;
public class HelloTest {
public static void main ( String [] args ) {
// Hello hello = name -> System.out.println(name);
Hello hello = System . out :: println ;
hello . sayHello ( "Marry" );
}
}

**3.**Lambda 表达式延迟执行

应用场景

在某种条件下才会处理数据

示例

package com . wq . lambda . lazy ;
public interface MsgBuilder {
String buildMsg ( String ... infos );
}
package com . wq . lambda . lazy ;
public class PrintUtil {
public static void print ( boolean valid , String msg ){
if ( valid ){
System . out . println ( msg );
}
}
private static String build ( String ... infos ){
StringBuilder builder = new StringBuilder ();
for ( String info : infos ){
builder . append ( info );
}
return builder . toString ();
}
public static void print ( boolean valid , String ... infos ){
if ( valid ){
// MsgBuilder builder = new MsgBuilder() {
// @Override
// public String buildMsg(String... infos) {
// return PrintUtil.build(infos);
// }
// };
// MsgBuilder builder = (String... arr) -> {
// return PrintUtil.build(arr);
// };
// MsgBuilder builder = arr -> PrintUtil.build(arr);
MsgBuilder builder = PrintUtil :: build ;
System . out . println ( builder . buildMsg ( infos ));
}
}
}
package com . wq . lambda . lazy ;
public class PrintTest {
public static void main ( String [] args ) {
String name = "Marry" ;
String desc = " is friendly" ;
//不会打印任何信息,但是此时已经完成了字符串的组装,这是属于性能上的浪费
PrintUtil . print ( false , name + desc );
//不会打印任何信息,但是也未构建字符串
PrintUtil . print ( false , name , desc );
//会打印信息时才会构建字符串
PrintUtil . print ( true , name , desc );
}
}

**4.**Consumer 接口

void accept ( T t ); // 接收一个被消费的数据

解释说明

Consumer 顾名思义就是消费者的意思。可以消费一个被接收到的数据,至于如何消费,就需要看这个接口被如何实现。

示例

package com . wq . consumer ;
import java . util . Arrays ;
import java . util . HashSet ;
import java . util . List ;
import java . util . Set ;
import java . util . function . Consumer ;
public class ConsumerTest {
public static void main ( String [] args ) {
// Consumer<String> c1 = new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s);
// }
// };
// Consumer<String> c1 = (String s) -> {
// System.out.println(s);
// };
// Consumer<String> c1 = s -> System.out.println(s);
Consumer < String > c1 = System . out :: println ;
c1 . accept ( " 这是被消费的信息 " );
// Consumer<String> c2 = new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s.charAt(0));
// }
// };
Consumer < String > c2 = s -> System . out . println ( s . charAt ( 0 ));
c2 . accept ( "This is a consumer" );
Consumer < String > c3 = c1 . andThen ( c2 );
c3 . accept ( " 先打印再取第一个字符 " );
//将数组转换为集合
List < Integer > numbers = Arrays . asList ( 1 , 2 , 3 , 4 , 5 );
// numbers.forEach(new Consumer<Integer>() {
// @Override
// public void accept(Integer integer) {
// System.out.println(integer);
// }
// });
//
// numbers.forEach(integer -> System.out.println(integer));
numbers . forEach ( System . out :: println );
Set < String > names = new HashSet <> ();
names . add ( "admin" );
names . add ( "test" );
names . add ( "developer" );
// names.forEach(new Consumer<String>() {
// @Override
// public void accept(String s) {
// System.out.println(s);
// }
// });
names . forEach ( System . out :: println );
}
}

**5.**BiConsumer 接口

void accept ( T t , U u ); // 接收两个被消费的数据

解释说明

BiConsumer 也是一个消费者,只是这个消费者可以一次性消费两个数据(一般是键值对)。至于如何消费,就需要看这个接口被如何实现。

示例

package com . wq . consumer ;
import java . util . HashMap ;
import java . util . Map ;
import java . util . function . BiConsumer ;
public class BiConsumerTest {
public static void main ( String [] args ) {
// BiConsumer<String,Integer> bc = new BiConsumer<String, Integer>() {
// @Override
// public void accept(String s, Integer integer) {
// System.out.println(s + "=>" + integer);
// }
// };
BiConsumer < String , Integer > bc = ( s , i ) -> System . out . println ( s + "=>" + i );
bc . accept ( "a" , 1 );
Map < String , String > counties = new HashMap <> ();
counties . put ( "CN" , " 中国 " );
counties . put ( "EN" , " 英国 " );
counties . put ( "US" , " 美国 " );
// counties.forEach(new BiConsumer<String, String>() {
// @Override
// public void accept(String s1, String s2) {
// System.out.println(s1 + "=>" + s2);
// }
// });
counties . forEach (( s1 , s2 ) -> System . out . println ( s1 + "=>" + s2 ));
}
}

**6.**Predicate 接口

boolean test ( T t ); // 检测是否满足条件
default Predicate < T > and ( Predicate <? super T > other ); // 条件之间的逻辑与衔接
default Predicate < T > negate (); // 条件取反
default Predicate < T > or ( Predicate <? super T > other ); // 条件之间的逻辑或衔接

解释说明

Predicate 是条件的意思,可以检测给定数据是否满足条件,也可以与其他条件进行衔接。至于如何检测,就需要看这个接口被如何实现。

示例

import java . util . function . Predicate ;
public class PredicateTest {
public static void main ( String [] args ) {
// Predicate<String> p1 = new Predicate<String>() {
// @Override
// public boolean test(String s) {
// return s.contains("中国");
// }
// };
Predicate < String > p1 = s -> s . contains ( " 中 " );
boolean result1 = p1 . test ( " 中华人民共和国 " );
System . out . println ( result1 );
Predicate < String > p2 = s -> s . indexOf ( " 啊 " ) > 0 ;
boolean result2 = p2 . test ( " 中华人民共和国 " );
System . out . println ( result2 );
Predicate < String > p3 = p1 . negate (); // 取反
System . out . println ( p3 . test ( " 中华人民共和国 " ));
Predicate < String > p4 = p1 . and ( p2 ); // 逻辑与衔接
System . out . println ( p4 . test ( " 中华人民共和国 " ));
Predicate < String > p5 = p1 . or ( p2 ); // 逻辑或衔接
System . out . println ( p5 . test ( " 中华人民共和国 " ));
}
}

练习

学生有姓名、性别和年龄。现有一个集合内存储有10 名学生信息,请找出其中性别为男,年龄在 20 岁以上的学生,并在控制台进行输出

package com . wq . predicate ;
public class Student {
private String name ;
private String sex ;
private int age ;
public Student ( String name , String sex , int age ) {
this . name = name ;
this . sex = sex ;
this . age = age ;
}
public String getName () {
return name ;
}
public void setName ( String name ) {
this . name = name ;
}
public String getSex () {
return sex ;
}
public void setSex ( String sex ) {
this . sex = sex ;
}
public int getAge () {
return age ;
}
public void setAge ( int age ) {
this . age = age ;
}
@Override
public String toString () {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}' ;
}
}
package com . wq . predicate ;
import java . util . Arrays ;
import java . util . List ;
import java . util . function . Consumer ;
import java . util . function . Predicate ;
public class Exercise {
public static void main ( String [] args ) {
List < Integer > numbers = Arrays . asList ( 1 , 2 , 3 , 4 , 5 );
List < Student > students = Arrays . asList (
new Student ( " 管理员 1" , " 男 " , 20 ),
new Student ( " 管理员 2" , " 女 " , 21 ),
new Student ( " 管理员 3" , " 男 " , 22 ),
new Student ( " 管理员 4" , " 女 " , 23 ),
new Student ( " 管理员 5" , " 男 " , 24 ),
new Student ( " 管理员 6" , " 女 " , 18 ),
new Student ( " 管理员 7" , " 男 " , 16 ),
new Student ( " 管理员 8" , " 女 " , 19 ),
new Student ( " 管理员 9" , " 男 " , 20 ),
new Student ( " 管理员 0" , " 女 " , 23 )
);
// Predicate<Student> p1 = new Predicate<Student>() {
// @Override
// public boolean test(Student student) {
// return "男".equals(student.getSex());
// }
// };
Predicate < Student > p1 = stu -> " 男 " . equals ( stu . getSex ());
Predicate < Student > p2 = stu -> stu . getAge () > 20 ;
Predicate < Student > p3 = p1 . and ( p2 );
// students.forEach(new Consumer<Student>() {
// @Override
// public void accept(Student student) {
// if(p3.test(student)){
// System.out.println(student);
// }
// }
// });
students . forEach ( student -> {
if ( p3 . test ( student )){
System . out . println ( student );
}
});
}
}

**7.**Function 接口

R apply ( T t ); // 将一个对象转换为另一种数据类型的对象
default < V > Function < T , V > andThen ( Function <? super R , ? extends V >
after ); // 复合转换

解释说明

Function 是功能的意思,可以将一种数据类型的对象转换为另一种数据类型的对象,至于如何转换,就需要看这个接口被如何实现。

示例

import java . util . function . Function ;
public class FunctionTest {
public static void main ( String [] args ) {
// Function<String,Integer> f1 = new Function<String, Integer>() {
// @Override
// public Integer apply(String s) {
// return Integer.parseInt(s);
// }
// };
// Function<String,Integer> f1 = s -> Integer.parseInt(s);
Function < String , Integer > f1 = Integer :: parseInt ;
Integer i = f1 . apply ( "123" );
System . out . println ( i );
// Function<Integer,Double> f2 = new Function<Integer, Double>() {
// @Override
// public Double apply(Integer integer) {
// return integer * 10.0;
// }
// };
Function < Integer , Double > f2 = integer -> integer * 10.0 ;
System . out . println ( f2 . apply ( i ));
Function < String , Double > f3 = f1 . andThen ( f2 );
double d = f3 . apply ( "5" );
System . out . println ( d );
}
}

练习

现有文本存储学生信息如下:

谢霆锋 , 男 ,37
刘德华 , 男 ,52
郭富城 , 男 ,46
张学友 , 男 ,40
要求将学生信息从文本中读取出来并转换为学生对象,然后存储在集合中
import java . io . BufferedReader ;
import java . io . FileNotFoundException ;
import java . io . FileReader ;
import java . io . IOException ;
import java . util . ArrayList ;
import java . util . List ;
import java . util . function . Function ;
public class Exercise {
public static void main ( String [] args ) {
String path = "F:/stu.txt" ;
// Function<String, Student> function = new Function<String, Student>() {
// @Override
// public Student apply(String s) {
// return new Student(s.split(","));
// }
// };
Function < String , Student > function = s -> new
Student ( s . split ( "," ));
List < Student > students = readStudent ( path , function );
students . forEach ( System . out :: println );
System . out . println ( "========================" );
// Function<String[], Student> f = new Function<String[], Student> () {
// @Override
// public Student apply(String[] strings) {
// return new Student(strings);
// }
// };
// Function<String[], Student> f = strings -> new Student(strings);
Function < String [], Student > f = Student :: new ;
List < Student > stus = readStudent1 ( path , f );
stus . forEach ( System . out :: println );
}
public static List < Student > readStudent1 ( String path ,
Function < String [], Student > function ){
List < Student > students = new ArrayList <> ();
try ( FileReader reader = new FileReader ( path );
BufferedReader br = new BufferedReader ( reader )) {
String line ;
while (( line = br . readLine ()) != null ){
String [] arr = line . split ( "," );
Student stu = function . apply ( arr );
students . add ( stu );
}
} catch ( FileNotFoundException e ) {
e . printStackTrace ();
} catch ( IOException e ) {
e . printStackTrace ();
}
return students ;
}
public static List < Student > readStudent ( String path , Function < String , Student > function ){
List < Student > students = new ArrayList <> ();
try ( FileReader reader = new FileReader ( path );
BufferedReader br = new BufferedReader ( reader )) { String line ;
while (( line = br . readLine ()) != null ){
Student stu = function . apply ( line );
students . add ( stu );
}
} catch ( FileNotFoundException e ) {
e . printStackTrace ();
} catch ( IOException e ) {
e . printStackTrace ();
}
return students ;
}
private static class Student {
private String name ;
private String sex ;
private int age ;
public Student ( String [] arr ) {
this . name = arr [ 0 ];
this . sex = arr [ 1 ];
this . age = Integer . parseInt ( arr [ 2 ]);
}
public String getName () {
return name ;
}
public void setName ( String name ) {
this . name = name ;
}
public String getSex () {
return sex ;
}
public void setSex ( String sex ) {
this . sex = sex ;
}
public int getAge () {
return age ;
}
public void setAge ( int age ) {
this . age = age ;
}
@Override
public String toString () {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}' ;
}
}
}

相关推荐
乌啼霜满天2493 分钟前
Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
java·spring boot·spring·mvc
tangliang_cn8 分钟前
java入门 自定义springboot starter
java·开发语言·spring boot
程序猿阿伟9 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
Grey_fantasy19 分钟前
高级编程之结构化代码
java·spring boot·spring cloud
新知图书20 分钟前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
威威猫的栗子22 分钟前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python
力透键背22 分钟前
display: none和visibility: hidden的区别
开发语言·前端·javascript
bluefox197923 分钟前
使用 Oracle.DataAccess.Client 驱动 和 OleDB 调用Oracle 函数的区别
开发语言·c#
弗锐土豆26 分钟前
工业生产安全-安全帽第二篇-用java语言看看opencv实现的目标检测使用过程
java·opencv·安全·检测·面部
Elaine20239126 分钟前
零碎04 MybatisPlus自定义模版生成代码
java·spring·mybatis