常用的函数式接口
JDK提供了大量常用的函数式接口以丰富Lambda的典型使用场景,它们主要在java.util.function包中被提供。
Supplier接口
java.util.function.Supplier接口仅包含一个无参的方法:T get()。
用来获取一个泛型参数指定类型的对象数据。由于这是一个函数式接口,这也就意味着对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。
import java.util.function.Supplier;
public class Tets {
public static void main(String[] args) {
/*String suplier = getSuplier(new Supplier<String>() {
@Override
public String get() {
return "你好";
}
});*/
String suplier = getSuplier(() -> "你好");
System.out.println(suplier);
}
public static String getSuplier(Supplier<String> su) {
return su.get();
}
}
Consumer接口
java.util.function.Consumer接口则正好与Supplier接口相反,它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定。
抽象方法:accept
Consumer接口中包含抽象方法void accept(T t),意为消费一个指定泛型的数据。
import java.util.function.Consumer;
public class Test1 {
public static void main(String[] args) {
String s="你好";
getConsumer(s,(a)-> System.out.println(s));
/* getConsumer(s, new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});*/
}
public static void getConsumer(String s, Consumer<String> con){
con.accept(s);
}
}
当然,更好的写法是使用方法引用。
默认方法:andThen
如果一个方法的参数和返回值全都是Consumer类型,那么就可以实现效果:消费数据的时候,首先做一个操作,然后再做一个操作,实现组合。而这个方法就是Consumer接口中的default方法andThen。
备注:java.util.Objects的requireNonNull静态方法将会在参数为null时主动抛出NullPointerException异常。这省去了重复编写if语句和抛出空指针异常的麻烦。
对一个字符串进行变换。
import java.util.function.Consumer;
public class Test2 {
public static void main(String[] args) {
String s=”hello”;
getConsumer(s,(a)->{
String s1 = s.toUpperCase();//把原先的字符变成大写
System.out.println(“s1:”+s1);
},(b)->{
String ss=(s.charAt(0)+”“).toUpperCase(); //首字母大写
System.out.println(“ss “+ss);
String ss1=s.substring(1,s.length()); //截取其他字符
System.out.println(“ss1 “+ss1);
String sss=ss+ss1; //组合字符
System.out.println(sss);
});
}
public static void getConsumer(String s,Consumer<String> con1,Consumer<String > con2){
con1.andThen(con2).accept(s);
}
}
要想实现组合,需要两个或多个Lambda表达式即可,而andThen的语义正是“一步接一步”操作。
Predicate接口
有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用java.util.function.Predicate接口。
抽象方法:test
默认方法:and
既然是条件判断,就会存在与、或、非三种常见的逻辑关系。其中将两个Predicate条件使用“与”逻辑连接起来实现“并且”的效果时,可以使用default方法and。
默认方法:or
如果希望实现逻辑“字符串包含大写H或者包含大写W”,那么代码只需要将“and”修改为“or”名称即可,其他都不变:
import java.util.function.Predicate;
public class Test3 {
public static void main(String[] args) {
boolean predicate = getPredicate((s) -> {
if (s.length() > 5) {
return true;
} else {
return false;
}
});
System.out.println(predicate);
}
public static boolean getPredicate(Predicate<String> pre){
return pre.test("hellojava");
}
}
/*判断一个字父知否符合一定的规则
* 1)首字母是否为大写A
* 2)末尾字符是否为数字
* 3)只符合一条则为true
*
* 注意最后一个字符判断数字怎么判断。
* */
import java.util.function.Predicate;
public class test4 {
public static void main(String[] args) {
String s1 = “Akhksf12”;
testPredicate(s1,
(a) -> {
if (a.charAt(0) == ‘A’) {
return true;
}else {
return false;
}
},
(b) -> {
int c = (int)b.charAt(b.length() - 1);
if (c >= '0'&& c <= '9') {
return true;
}else {
return false;
}
});
}
public static void testPredicate(String s, Predicate<String> s1, Predicate<String> s2) {
boolean test = s1.and(s2).test(s);
System.out.println(test); //test()方法里面的为要使用的那个东西,如果不进行赋值
//则需要进行传递
}
}
默认方法:negate
“与”、“或”已经了解了,剩下的“非”(取反)也会简单。默认方法negate的
从实现中很容易看出,它是执行了test方法之后,对结果boolean值进行“!”取反而已。一定要在test方法调用之前调用negate方法,正如and和or方法一样:
Function接口
java.util.function.Function