在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理Java知识点的第三十四篇博客。
本篇博客介绍了Java的函数式接口。
本系列博客所有Java代码都使用IntelliJ IDEA编译运行,版本为2022.1。所用JDK版本为JDK11。
目录
函数式接口
函数式接口概述
函数式接口是只有一个抽象方法的接口。
Java中函数式编程的体现是Lambda表达式,函数式接口就是可以用于Lambda使用的接口。只有接口中只有一个抽象方法,Lambda才能顺利进行推导。
可以将@FunctionalInterface放在接口定义上方判断是否为函数式接口,是则编译通过,否则编译失败。
public interface functionalinterface {
public void show();
}
functionalinterface是一个函数式接口,只有一个抽象方法show。
public class functionaluse {
public static void main(String[] args){
functionalinterface fl = (() ->{
System.out.println("A new knowledge");
});
fl.show();
}
}
程序的输出是:
A new knowledge
函数式接口作为方法的参数
public class functionalthread {
public static void main(String[] args){
test(new Runnable(){
public void run(){
System.out.println(Thread.currentThread() + " start");
}
});
test(()-> {
System.out.println(Thread.currentThread() + " start");
});
}
public static void test(Runnable r){
Thread t = new Thread(r);
t.start();
}
}
test方法接受一个实现Runnable的类,并启动多线程。
程序的输出是:
Thread[Thread-0,5,main] start
Thread[Thread-1,5,main] start
函数式接口作为方法的返回值
如果方法的返回值是一个函数式接口,我们可以使用Lambda表达式作为结果返回。
import java.util.Comparator;
import java.util.ArrayList;
public class returnfunctional {
public static void main(String[] args){
ArrayList<String> ar = new ArrayList<String>();
ar.add("aaaa");
ar.add("bb");
ar.add("ccc");
ar.add("d");
System.out.println(ar);
ar.sort(getcomparator());
System.out.println(ar);
}
public static Comparator<String> getcomparator(){
return ((String a,String b)->{
return a.length() - b.length();
});
}
}
getcomparator方法返回一个比较器。程序的输出是:
[aaaa, bb, ccc, d]
[d, bb, ccc, aaaa]
常用的函数式接口
Java8在java.util.function包下定义了大量函数式接口,如Supplier接口,Consumer接口,Predicate接口,Function接口等。
Supplier接口
Supplier<T>包含一个无参方法:
T get()获得结果。
该方法不需要参数,会按照某种实现逻辑(由Lambda表达式实现)返回一个数据。
Supplier<T>接口被称为生产型接口,如果指定了接口的泛型是什么类型,那么接口的get方法会生产什么类型的数据。
import java.util.function.Supplier;
public class supplier1 {
public static void main(String[] args){
String s = getstring(() -> {
return "Good afternoon";
});
System.out.println(s);
Integer i =getint(() -> {
return 14;
});
System.out.println(i);
}
public static String getstring(Supplier<String> sup){
return sup.get();
}
public static Integer getint(Supplier<Integer> sup){
return sup.get();
}
}
程序的输出是:
Good afternoon
14
import java.util.function.Supplier;
public class supplier2 {
public static void main(String[] args){
int[] arr = new int[]{19,50,28,37,46};
int arrmax = getmax(() -> {
int max, i;
max = arr[0];
for(i = 0; i < arr.length;i += 1){
if(arr[i] > max){
max = arr[i];
}
}
return max;
});
System.out.println(arrmax);
}
public static int getmax(Supplier<Integer> sup){
return sup.get();
}
}
重写get方法,使其获得int数组的最大值。程序的输出是:
50
Consumer接口
Consumer<T>包含两个方法:
void accept(T t)对给定的参数执行操作。
default Consumer<T> andThen(Consumer after)返回一个组合的Consumer,依次执行此操作,然后执行after操作。
Consumer<T>接口被称为消费型接口,消费的数据类型由泛型指定。
import java.util.function.Consumer;
public class consumer1 {
public static void main(String[] args){
constring("Supplier and Consumer",(String s) -> {
System.out.println(s);
});
constring("Supplier and Consumer",(String s) -> {
System.out.println(s);
},(String s) -> {
System.out.println(new StringBuilder(s).reverse().toString());
});
}
public static void constring(String s, Consumer<String> con){
con.accept(s);
}
public static void constring(String s, Consumer<String> con1, Consumer<String> con2){
con1.andThen(con2).accept(s);
}
}
程序的输出是:
Supplier and Consumer
Supplier and Consumer
remusnoC dna reilppuS
import java.util.function.Consumer;
public class consumer2 {
public static void main(String[] args){
String[] strarray = new String[]{"Allen,22","Gilbert,24","Wilma,27"};
constr(strarray,(String s) -> {
String name = s.split(",")[0];
System.out.print("The name is " + name + " ");
},(String s) -> {
String age = s.split(",")[1];
System.out.println("and the age is " + age);
});
}
public static void constr(String[] strarray,Consumer<String> con1,Consumer<String> con2){
for(String s:strarray){
con1.andThen(con2).accept(s);
}
}
}
程序创建了一个存放String的数组strarray,存放了三个String类数组。constr成员方法中将此数组遍历,每个成员都执行碎开后输出相关信息的操作。
程序的输出是:
The name is Allen and the age is 22
The name is Gilbert and the age is 24
The name is Wilma and the age is 27
Predicate接口
Predicate<T>常用的四个方法是:
boolean test(T t)对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回boolean类型值。
default Predicate<T> negate()返回一个逻辑的否定,对应逻辑非。
default Predicate<T> and(Predicate other)返回一个组合判断,对应短路逻辑与。
default Predicate<T> or(Predicate other)返回一个组合判断,对应短路逻辑或。
Predicate<T>通常用于判断参数是否满足某一条件。
import java.util.function.Predicate;
public class predicate1 {
public static void main(String[] args){
boolean flag1 = prestr1("Hello",(String s) -> {
return s.length() > 7;
});
System.out.println(flag1);
boolean flag2 = prestr1("Hello Java",(String s) -> {
return s.length() > 7;
});
System.out.println(flag2);
boolean flag3 = prestr2("Hello",(String s) -> {
return s.length() > 7;
});
System.out.println(flag3);
boolean flag4 = prestr2("Hello Java",(String s) -> {
return s.length() > 7;
});
System.out.println(flag4);
}
public static boolean prestr1(String s, Predicate<String> pre){
return pre.test(s);
}
public static boolean prestr2(String s, Predicate<String> pre){
return pre.negate().test(s);
}
}
程序的输出是:
false
true
true
false
import java.util.function.Predicate;
public class predicate2 {
public static void main(String[] args){
boolean flag1 = prestr1("Hello",(String s) -> {
return s.length() < 10;
},(String s) -> {
return s.length() > 5;
});
System.out.println(flag1);
boolean flag2 = prestr1("August",(String s) -> {
return s.length() < 10;
},(String s) -> {
return s.length() > 5;
});
System.out.println(flag2);
boolean flag3 = prestr2("Hello",(String s) -> {
return s.length() < 10;
},(String s) -> {
return s.length() > 5;
});
System.out.println(flag3);
boolean flag4 = prestr2("August",(String s) -> {
return s.length() < 10;
},(String s) -> {
return s.length() > 5;
});
System.out.println(flag4);
}
public static boolean prestr1(String s,Predicate<String> pre1,Predicate<String> pre2){
return pre1.and(pre2).test(s);
}
public static boolean prestr2(String s,Predicate<String> pre1,Predicate<String> pre2){
return pre1.or(pre2).test(s);
}
}
程序的输出是:
false
true
true
true
import java.util.ArrayList;
import java.util.function.Predicate;
public class predicate3 {
public static void main(String[] args){
String[] strarray = new String[]{"Pamela,65,21","Peter,60,18","Paine,85,26","Paula,90,22","Pilar,45,15","Philippe,80,21",
"Paul,105,20","Patty,35,20","Priscilla,100,19","Pablo,70,23","Polo,100,18","Paulette,90,22"};
ArrayList<String> ar = prestr(strarray,(String s) ->{
String s1 = s.split(",")[1];
int strength = Integer.parseInt(s1);
return strength > 80;
},(String s) ->{
String s2 = s.split(",")[2];
int time = Integer.parseInt(s2);
return time > 18;
});
System.out.println(ar);
}
public static ArrayList<String> prestr(String[] strarray,Predicate<String> pre1,Predicate<String> pre2){
ArrayList<String> ar = new ArrayList<String>();
for(String s:strarray){
if(pre1.and(pre2).test(s) == true){
ar.add(s);
}
}
return ar;
}
}
这段代码实现了数据的筛选,在所有字符串中筛选出字符串碎开后第一个整数大于80且第二个整数大于18的字符串。
程序的输出是:
[Paine,85,26, Paula,90,22, Paul,105,20, Priscilla,100,19, Paulette,90,22]
Function接口
Function<T,R>常用的两个方法是:
R apply(T t)将此函数用于给定的参数。
default<V> Function andThen(Function after)返回一个组合函数,首先将该函数用于输入,然后将after函数用于结果。
Function<T,R>通常用于对参数进行处理,转换(逻辑由Lambda表达式实现),然后返回一个新的值。
import java.util.function.Function;
public class function1 {
public static void main(String[] args){
String str = "16";
fun1(str,(String s) -> {
return Integer.parseInt(s);
});
int number = 5;
fun2(number,(Integer num) -> {
num += 10;
return String.valueOf(num);
});
fun3(str,(String s) -> {
return Integer.parseInt(s);
},(Integer num) -> {
num += 10;
return String.valueOf(num);
});
}
public static void fun1(String str,Function<String,Integer> fun){
int num = fun.apply(str);
System.out.println(num);
}
public static void fun2(int num,Function<Integer,String> fun){
String str = fun.apply(num);
System.out.println(str);
}
public static void fun3(String s,Function<String,Integer> fun1,Function<Integer,String> fun2){
String str = fun1.andThen(fun2).apply(s);
System.out.println(str);
}
}
程序的输出是:
16
15
26
import java.util.function.Function;
public class function2 {
public static void main(String[] args){
String s = "Enrique,65";
tran(s,(String str)->{
return str.split(",")[1];
},(String str) ->{
return Integer.parseInt(str);
},(Integer i)->{
return i + 40;
});
}
public static void tran(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);
}
}
程序的输出是:
105