函数式接口
* 函数式接口:有且仅有一个抽象方法的接口。
* 适用于函数式编程的接口,java中体现为Lambda;
* lambda:延迟加载;使用前提:必须使用函数式接口;
* 格式:
* 修饰符 interface 接口名称{
* public abstract 返回值类型 方法名称(参数);
* }
public class FunctionInterfaceIntro {
public static void showlog(int level,MyFI fi){
if (level==1){
System.out.println(fi.method());
}
}
public static void main(String[] args) {
String s1="aaa";
String s2="bbb";
String s3="ccc";
/*此处使用匿名内部内,仅仅将参数传递到showlog方法中,满足条件才会调用接口
* 防止性能浪费,
* */
showlog(1,()->{
return s1+s2+s3;
});
}
}
Prac1
* 例如java.lang.runnable接口是一个函数式接口;
* 假设存在一个startThread方法使用接口作为参数,则使用Lambda进行传参,
* 与Thread类的构造方法参数为Runnable没有本质区别。
public class FIPrac1_FIasPara {
/*方法参数必须是函数式接口*/
public static void startThread(Runnable run){
new Thread(run).start();
}
public static void main(String[] args) {
// 匿名内部类方式
startThread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"启动了");
}
});
// lambda表示
startThread(()->System.out.println(Thread.currentThread().getName()+"启动了"));
}
}
Prac2
* 用一个方法来获取一个java.util.Comparator 接口类型的对象作为排序器,调用方法获取。
public class FIPrac2_FIasReturn {
public static Comparator<String> getComparator(){
return (String o1,String o2)->{
return o2.length()-o1.length();
};
/*优化表达式 :相同数据类型;return;{}
* return (o1, o2)-> o2.length()-o1.length();
* */
}
public static void main(String[] args) {
String[] srt={"aa","cccc","bbb","12222","9999999","11111"};
System.out.println(Arrays.toString(srt));
Arrays.sort(srt,getComparator());
System.out.println("sorted:"+ Arrays.toString(srt));
}
}
Consumer<T>
* java.util.function.Consumer<T>:消费一个数据。
* 抽象方法accept: void accept(T t),意为消费一个指定泛型类型的数据。
* 默认方法andThen: 方法与返回值都是Consumer类型,消费数据时,对两个操作组合,在对数据进行消费。
* 例子:
* Consumer<String> s1
* Consumer<String> s2
* s1.accept(String)
* s2.accept(String)
* 等价于:
* s1.andThen(s2).accept(String);
public class Intro {
public static void main(String[] args) {
System.out.println("=====================Accept==================");
consumeString(s -> System.out.println(s));
consumeString(s -> System.out.println(new StringBuffer(s).reverse().toString()));
System.out.println("=====================andThen==================");
/*匿名内部类基本格式 (对象)->{对象操作}*/
method("hElLo",(t)->{
System.out.println(t.toLowerCase());
},(t)->{
System.out.println(t.toUpperCase());
});
method2("HaPe",(t)->{
System.out.println(t.toLowerCase());
},(t)->{
System.out.println(t.toUpperCase());
});
}
public static void consumeString(Consumer<String> func){
func.accept("abcde");
}
public static void method(String s,Consumer<String> s1,Consumer<String> s2){
s1.accept(s);
s2.accept(s);
}
public static void method2(String s,Consumer<String> s1,Consumer<String> s2){
s1.andThen(s2).accept(s);
}
}
Prac
* 按照姓名xx,年龄xx打印
* 姓名作为第一个lambda实例
* 年龄作为第二个lambda实例
* 将其拼接
public class ConsumerPrac {
public static void main(String[] args) {
String[] str={"aaa,15","bbb,16","ccc,17"};
method(str,(s)->{
System.out.print("name:"+s.split(",")[0]);
},(s)->{System.out.println(",age:"+s.split(",")[1]); });
}
public static void method(String[] strs, Consumer<String> s1,Consumer<String> s2){
for (String str : strs) {
s1.andThen(s2).accept(str);
}
}
}
Supplier<T>
* java.util.function.Supplier<T>接口仅包含一个无参的方法:T_get(),获取泛型类型指定类型的对象数据。
* Supplier<T>被称为生产型接口,指定泛型的类型与get生产的类型相同。
public class Intro {
public static void main(String[] args) {
//定义一个方法,方法的参数传递Supplier<T>接口,泛型执行String.get方法,返回一个String
String s=re(()->{return "ccc"; });
String s2=re(()->"ccc");//进一步优化函数式接口,去掉return {} ;
//原始匿名内部类
String s3=re(new Supplier<String>() {
@Override
public String get() {
return null;
}
});
System.out.println(s);
}
public static String re(Supplier<String> sup){
return sup.get();
}
}
Prac
* 使用Supplier接口作为方法参数类型,通过lambda表达式求出int数组中的最大值,接口泛型使用java.lang.Integer
public class SupplierPrac {
public static void main(String[] args) {
int[] kk={4,3,6,1,7,5};
int max=getMax(()->{
int maxnum=kk[0];
for (int i = 0; i < kk.length; i++) {
if(kk[i]>maxnum){
maxnum=kk[i];
}
}
return maxnum;
});
System.out.println(max);
}
public static int getMax(Supplier<Integer> integerSupplier){
return integerSupplier.get();
}
}
Predicate<T>
* java.util.function.Predicate<T>:对某种类型的数据进行判断,从而得到一个boolean值结果。
* 抽象方法:boolean test(T t)
public class Intro {
public static void main(String[] args) {
String ss="SSSSSASDD";
boolean b=check(ss,(s)-> s.length()>5);
System.out.println(b);
}
public static boolean check(String s, Predicate<String> pre)
{
//返回值返回包含处理变量的函数式接口对象的抽象方法
return pre.test(s);
}
}
* Predict属于条件判断,存在与或非三种常见的逻辑关系
* 与:add;
* 或:Or;
* 非:negate;
public class MethodAnd {
public static void main(String[] args) {
String s = "ssssadadqweaf";
boolean b = methodAdd(s, (String st1) -> s.contains("s"), (String st2) -> s.contains("a"));
boolean b2 = methodOr(s, (String st1) -> s.contains("s"), (String st2) -> s.contains("a"));
boolean b3 = methodnegate(s, (String st1) -> s.contains("s"));
System.out.println(b);
System.out.println(b2);
System.out.println(b3);
}
public static boolean methodAdd(String s, Predicate<String> pre1, Predicate<String> pre2) {
// return pre1.test(s)&&pre2.test(s);
return pre1.and(pre2).test(s);
}
public static boolean methodOr(String s, Predicate<String> pre1, Predicate<String> pre2) {
//
return pre1.or(pre2).test(s);
}
public static boolean methodnegate(String s, Predicate<String> pre1) {
// return pre1.test(s)&&pre2.test(s);
return pre1.negate().test(s);//!pre.test(s)
}
}
Prac
* 对字符串进行筛选:
* 1,名字为4字
* 2,年纪为18以上
public class Prac {
public static void main(String[] args) {
String[] array={"aaaa,29","bbbbb,28","ccc,12","dddd,19"};
ArrayList<String> list=judge(array,(String s)->{
return s.split(",")[0].length()==4;
},(String s)->{
return Integer.parseInt(s.split(",")[1])>18;
});
for (String s : list) {
System.out.println(s);
}
}
public static ArrayList<String> judge(String[] str, Predicate<String> str1, Predicate<String> str2){
ArrayList<String> list=new ArrayList<>();
for (String s : str) {
boolean b=str1.and(str2).test(s);
if(b){
list.add(s);
}
}
return list;
}
}
Function<T,R>
* java.util.function.Function<T,R>接口用来根据一个类型的数据的到另一个类型的数据,前者称为前置条件,后者为后置条件(转换类型接口)
* 抽象方法:R apply (T t) 根据类型T的参数获取类型R的结果
public class Intro {
public static void main(String[] args) {
String s1="20";
method(s1,(String s2) -> Integer.parseInt(s2));
}
public static void method(String s,Function<String,Integer> fuc){
System.out.println(fuc.apply(s)+20);
}
}
* andThen:组合操作;
* 需求:
* 1,将String类型“123”转换为Integer,把转换的结果加10
* 2,把转换后的Integer类型数据,转换为String
public class methodAndThen {
public static void main(String[] args) {
String ss = "123";
method(ss, s1 ->
Integer.parseInt(s1) + 10
, s2 ->
String.valueOf(s2)
);
}
public static void method(String s, Function<String, Integer> func1, Function<Integer, String> func2) {
System.out.println((func1.andThen(func2).apply(s)));
}
}
Prac
* 使用Funciton进行函数模型的拼接
* String str="aaa,18"
* 截取数字部分,转换为int,加上100
public class Prac {
public static void main(String[] args) {
String str="aaa,18";
method(str,(s1)->Integer.parseInt(s1.split(",")[1])+100);
}
public static void method(String s, Function<String,Integer> func1){
System.out.println(func1.apply(s));
}
}