JavaEE学习日志持续更新----> 必看!JavaEE学习路线(文章总汇)
Java学习日志(十四)
函数式接口
函数式接口的定义
函数式接口:有且仅有一个抽象方法的接口(可以包含:默认,私有,静态)
注意:函数式接口一般作为方法的参数使用
自定义一个函数式接口
@FunctionalInterface
public interface MyFunctionalInterface {
//定义一个抽象方法
public abstract void method();
}
@FunctionalInterface
注解:检测一个接口是否为函数式接口
- 是:接口中有且仅有一个抽象方法
- 不是:代码会编译报错,接口中没有抽象方法,或抽象方法多于一个
函数式接口的使用
自定义函数式接口的实现类:
public class MyFunctionalInterfaceImpl implements MyFunctionalInterface{
@Override
public void method() {
System.out.println("实现类重写的method方法");
}
}
@Override
注解:检测一个方法是否为重写的方法,如果不是,则会编译报错
三种方法使用函数式接口:
首先定义一个方法,方法的参数使用函数式接口MyFunctionalInterface
public static void show(MyFunctionalInterface my){
my.method();
}
- 调用show方法,参数是一个接口,所以可以传递接口的实现类对象
public static void main(String[] args) {
//调用show方法,参数是一个接口,所以可以传递接口的实现类对象
show(new MyFunctionalInterfaceImpl());
}
- 调用show方法,参数是一个接口,所以可以传递接口的匿名内部类
public static void main(String[] args) {
show(new MyFunctionalInterface() {
@Override
public void method() {
System.out.println("匿名内部类执行的method方法");
}
});
}
- 调用show方法,参数是一个函数式接口,所以可以传递Lambda表达式
public static void main(String[] args) {
show(()->{
System.out.println("Lambda表达式执行的method方法");
});
}
常用函数式接口
java.util.function
Supplier接口
java.util.Supplier<泛型>:用来生产数据
抽象方法:
T get()
用来获取一个泛型参数指定类型的对象数据
作用:
Supplier接口指定什么泛型,就可以使用get方法,生产什么类型的数据
示例:
public class Demo01Supplier {
/*
定义一个方法,参数传递函数式接口Supplier,泛型使用String
方法内部使用Supplier接口中的方法get,生产一个字符串并返回。
*/
public static String getString(Supplier<String> sup){
return sup.get();
}
public static void main(String[] args) {
//调用getString方法,方法的参数是函数式接口,所以可以使用Lambda表达式重写get方法
String s = getString(() -> {
return "aaa";
});
System.out.println(s);
}
}
练习:使用Supplier接口作为方法参数类型,通过Lambda表达式求出int数组的最大值
public class Demo02Supplier {
/*
定义一个方法
参数传递Supplier接口,泛型使用Integer
方法内使用Supplier接口的get方法返回数组的最大值
*/
public static int getMax(Supplier<Integer> sup){
return sup.get();
}
public static void main(String[] args) {
//定义一个数组
int[] arr = {11,-33,321312,433};
//调用getMath方法
int max = getMax(() -> {
//获取数组最大值的过程
int m = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > m) {
m = arr[i];
}
}
return m;
});
System.out.println(max);
}
}
Consumer接口
java.util.function.Consumer<泛型>:用于消费数据
抽象方法:
void accept(T t)
消费一个指定泛型的数据
作用:
使用Consumer接口中的方法accept消费指定泛型的数据,至于怎么消费这个数据,需要自己定义(Lambda表达式中)
示例:
public class Demo01Consumer {
/*
定义一个方法,参数传递一个字符串,传递一个Consumer接口,泛型使用字符串
方法内部使用Consumer接口中的方法accept消费传递的字符串
*/
public static void print(String s, Consumer<String> con){
con.accept(s);
}
public static void main(String[] args) {
//调用print方法
print("abc",(String s)->{
System.out.println(s);
});
print("abc",(String s)->{
//打印反向字符串
System.out.println(new StringBuilder(s).reverse().toString());
});
}
}
默认方法:
Consumer<T> andThen(Consumer<? super T> after)
源码:
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (t) -> {
this.accept(t);
after.accept(t);
};
}
作用:用于连接两个Consumer接口,一个是调用andThen方法的Consumer接口this,一个是andThen方法的参数after。
con1.andThen(con2).accept(s);
等价于con1.accept(s);con2.accept(s);
示例:
public class Demo02 {
/*
定义一个方法
参数传递字符串
参数传递两个Consumer接口,泛型都使用字符串
*/
public static void print(String s, Consumer<String> con1,Consumer<String> con2){
//使用con1使用一次字符串
//con1.accept(s);
//使用con2使用一次字符串
//con2.accept(s);
//使用andThen方法连接两个consumer接口,再进行消费
con1.andThen(con2).accept(s);//等价于con1.accept(s);con2.accept(s);
}
public static void main(String[] args) {
//调用print方法
print("abc",(String s)->{
System.out.println(s+"正在洗碗");
},(String s)->{
System.out.println(s+"正在扫地");
});
}
}
Function接口
java.util.function.Function<T,R>:用于类型转换
抽象方法:
R apply (T t)
根据类型T的参数获取类型R的结果
作用:把一种数据类型的数据,转换为另一种数据类型
示例:把String类型转换为Integer类型
public class Demo01 {
/*
定义一个方法
参数传递一个字符串类型的整数
参数传递Function<String,Integer>接口
*/
public static void stringToInteger(String s, Function<String,Integer> fun){
//使用apply方法进行类型转换
Integer in = fun.apply(s);
System.out.println(in);
}
public static void main(String[] args) {
//调用stringToInteger方法
stringToInteger("123",(String s)->{
//把字符串类型的整数转化为Integer类型
return Integer.parseInt(s);
});
}
}
练习:使用Function接口,传递字符串的姓名,返回Person类型的人
public class Demo02 {
/*
定义一个方法
参数传递字符串的姓名
参数传递Function<String,Person>接口
*/
public static void stringToPerson(String name, Function<String,Person> fun){
Person p = fun.apply(name);
System.out.println(p);
}
public static void main(String[] args) {
//调用stringToPerson方法
stringToPerson("abc",(String name)->{
return new Person(name);
});
}
}
默认方法:Function<T, V> andThen(Function<? super R, ? extends V> after)
源码:
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (t) -> {
this.accept(t);
after.accept(t);
};
}
作用:把两个Function接口组合到一起,一个是调用andThen方法的Function接口this,另一个是andThen方法的参数Function接口after
after.apply(this.apply(t))
this先对数据进行转化,再把转化的结果作为after的参数再进行一次转化
fun1.andThen(fun2).apply(s);
等价于
Integer in = fun1.apply(s);Integer in2 = fun2.apply(in);
示例:把String类型的"123",转化为Integer类型,把Integer类型123乘以10
“123”->123*10->1230
public class Demo03 {
/*
定义一个方法
参数传递字符串类型的整数
传递两个Function接口
*/
public static void reverse(String s, Function<String, Integer> fun1, Function<Integer, Integer> fun2) {
//"123"->123
//Integer in = fun1.apply(s);
//123*10
//Integer in2 = fun2.apply(in);
//使用andThen方法连接两个接口
fun1.andThen(fun2).apply(s);
}
public static void main(String[] args) {
//调用reverse方法
reverse("123", (String s) -> {
//"123"->123
return Integer.parseInt(s);
}, (Integer in) -> {
//123*10
return in * 10;
});
}
}
Predicate接口
java.util.function.Predicate<泛型>:用于数据判断
抽象方法:
boolean test(T t)
对某种类型的数据进行判断,从而得到一个boolean值
作用:
Predicate接口指定什么泛型,就可以对什么类型的数据进行判断
示例:
public class Demo01 {
/*
定义一个方法
参数传递一个字符串,参数传递Predicate接口,泛型使用String
*/
public static void check(String s, Predicate<String> pre){
//使用test方法,对字符串进行判断
boolean b = pre.test(s);
System.out.println(b);
}
public static void main(String[] args) {
//调用check方法
check("abc",(String s)->{
//判断字符串是否包含a
return s.contains("a");//true
});
check("abc",(String s)->{
//判断字符串长度是否大于5
return s.length()>5;//false
});
}
}
默认方法:
Predicate<T> and(Predicate<? super T> other)
Predicate<T> or(Predicate<? super T> other)
Predicate<T> negate()
注意:
- and方法与逻辑运算符&&功能相同
- or方法与逻辑运算符||功能相同
- negate方法与逻辑运算符!功能相同
代码等价示例:
定义一个方法参数传递字符串和两个Predicate接口,泛型都使用String
public static void check(String s, Predicate<String> pre1,Predicate<String> pre2){
//方法体
}
- and
boolean b = pre1.and(pre2).test(s);
等价于
boolean b = pre1.test(s) && pre2.test(s);
- or
boolean b = pre1.or(pre2).test(s);
等价于
boolean b = pre1.test(s) || pre2.test(s);
定义一个方法参数传递字符串和一个Predicate接口,泛型使用String
public static void check(String s, Predicate<String> pre){
//方法体
}
- negate
boolean b = !pre.test(s)
等价于
boolean b = pre.negate().test(s);