H3_常用的函数式接口

  1. java.util.function. Supplier 接口仅包含一个无参的方法:T get()。用来获取一个泛型参数指定类型的对象数据
  • Supplier接口被称为生产型接口,接口指定的泛型是什么类型,那么接口的get方法就会生产什么类型的数据
//  java.util.function.Supplier<T>
public class D05Supplier {
	//定义一个方法,方法的参数传递Supplier<T>接口,泛型指定String类型,get方法就会返回一个String
	public static String getString(Supplier<String> sup) {
		return sup.get();
	}
	public static void main(String[] args) {
		//调用getString,方法的参数是一个函数式接口,所以可以传递Lambda表达式
		String s = getString(()->{  //重写get()
			//生产一个字符串,并返回
			return "泡泡";
		});
		System.out.println(s);  //泡泡
		
		//优化
		String s2 = getString(()-> "泡泡");
		System.out.println(s2);
	}
}

  1. java.util.function. Consumer 接口正好与Supplier相反
    它不是生产一个数据,而是消费一个数据,其数据类型由泛型决定。
  • Consumer接口中包含的抽象方法void accept(T t),意为消费一个指定泛型的数据

  • Consumer接口是一个消费型接口,泛型指定什么类型,就可以使用accept方法消费什么类型的数据
    至于具体怎么消费(使用),需要自定义(输出…计算…)

01 void accept(T t)

// java.util.function.Consumer<T> 
public class D06Consumer {
	/*
	 	定义一个方法
	 	方法的参数是一个字符串的姓名
	 	方法的参数传递Consumer接口,泛型使用String
	 	可以使用Consumer接口消费字符串的姓名
	 */
	public static void method(String name,Consumer<String> con) {
		con.accept(name);  //具体怎么处理使用Lambda
	}
	public static void main(String[] args) {
		//调用method方法,传递字符串姓名,方法的另一个参数是Consumer接口,是一个函数式接口,所以可以传递Lambda表达式
		method("泡仔", (String name)->{
			//对传递的字符串进行消费
//			System.out.println(name);  //输出字符串
			
			//消费:把字符串进行反转
			String reName = new StringBuilder(name).reverse().toString();  //连式编程
			System.out.println(reName); //仔泡
		});
	}
}

02 Consumer接口的默认方法andThen

  • 作用:需要两个Consumer接口,可以把两个Consumer接口组合到一次,再对数据进行消费
  • 例如:
    Consumer con1
    Consumer con2
    String s = “hello”
    con1.accept(s);
    con2.accept(s);
  • 消费同一份数据—进行优化:
    连接两个Consumer接口,再进行消费
    con1.andThen(con2).accept(s):谁写前面,谁先消费

public class D06Consumer2 {
	//定义一个方法,方法的参数传递一个字符串和两个Consumer接口,泛型使用String
	public static void method(String s,Consumer<String> con1,Consumer<String> con2) {
//		con1.accept(s);
//		con2.accept(s);
		//可以使用andThen,把两个Consumer接口连接到一起再消费
		con1.andThen(con2).accept(s);  //con1连接con2,先执行con1消费数据,再执行con2消费数据
		
	}
	public static void main(String[] args) {
		//调用method,参数接口用Lambda替代
		method("Hello",
			(t)->{
				//消费方式:把字符串转换为大写
				System.out.println(t.toUpperCase());  //HELLO
			}, 
			(t)->{
				//消费方式:把字符串转换为小写
				System.out.println(t.toLowerCase());  //hello
			});
	}
}

// 练习

/*
 	练习:格式化打印机
 		字符串数组中有很多条信息,请请按照格式“姓名:xx。性别:xx。”的格式将信息打印出来
 		要求打印姓名的动作作为第一个Consumer接口的Lambda实例
 		将打印性别的动作作为第二个Consumer接口的Lambda实例
 		将两个Consumer接口按照顺序“拼接”到一起
 */
public class D06Test {
	public static void formatString(String[] arr,Consumer<String> con1,Consumer<String> con2) {
		for (String msg : arr) {
			//使用andThen方法连接两个Consumer接口,消费字符串
			con1.andThen(con2).accept(msg);
		}
	}
	public static void main(String[] args) {
		//定义一个字符串类型数组
		String[] arr = {"迪丽热巴,女","古力娜扎,女","马尔扎哈,男"};
		formatString(arr, (msg)->{
			String name  = msg.split(",")[0];  //获取姓名
			System.out.print("姓名:"+name);
		},(msg)->{
			String sex  = msg.split(",")[1];  //获取性别
			System.out.println(",性别:"+sex+"。");
		});
	}
}

  1. java.util.function. Predicate 接口
    作用:对某种数据类型的数据进行判断,返回布尔值
  • 01 Predicate接口中包含一个抽象方法
    boolean test​(T t):用来对指定数据类型数据进行判断的方法
    结果:
    符合条件:返回true
    不符合条件:返回false
public class D07Predicate {
	/*
	 	定义一个方法,参数传递String类型的字符串
	 	传递一个Predicate接口,泛型使用String
	 	使用Predicate中的方法test对字符串进行判断,并把判断的结果返回
	 */
	public static boolean checkString(String s,Predicate<String> pre) {
		return pre.test(s);
	} 
	public static void main(String[] args) {
		String s = "abcde";
		/*
		boolean b = checkString(s, (String str)->{
			//对参数传递的字符串进行判断,判断字符串长度是否大于5
			return str.length()>5; 
		});
		*/
		//优化
		boolean b = checkString(s, str-> str.length()>5);
		System.out.println(b);//false
	}
}
  • 02 默认方法:and
    逻辑表达式:可以连接多个判断条件
    &&:与运算符,有false则false
    ||:或运算符:有true则true
    !:非(取反)运行符,非真则假,非假则真

    需求:判断一个字符串,有两个判断的条件
    1 字符串的长度是否大于5
    2 字符串中是否包含a
    两个条件必须同时满足,我们可以使用&&运算符连接两个条件

    Preficate接口中有一个方法and,表示并且关系,也可以用于连接两个判断条件

      default Predicate<T> and(Predicate<? super T> other) {
      Objects.requireNonNull(other);
      // 方法内部的两个判断条件也是使用&&运算符连接起来的
      return (t) ‐> this.test(t) && other.test(t);  
      }
    
public class D07Predicate2 {
	/*
	 	定义一个方法,方法的参数传递一个字符串,传递两个Predicate接口
	 	1 字符串的长度是否大于5
 		2 字符串中是否包含a
 		两个条件必须同时满足
	 */
	public static boolean checkString(String str,Predicate<String> pre1,Predicate<String> pre2) {
//		return pre1.test(str) && pre2.test(str);
		return pre1.and(pre2).test(str);  //等价写法
	}
	public static void main(String[] args) {
		String s = "abcdef";
		boolean b = checkString(s, (String str)->{
			return str.length()>5;
		}, (String str)->{
			return str.contains("a");
		});
		System.out.println(b);  //true
	}
	
}
  • 03 默认方法:or
    Preficate接口中有一个方法or,表示或者关系,可以用于连接两个判断条件

      default Predicate<T> or(Predicate<? super T> other) {
      	Objects.requireNonNull(other);
      	return (t) ‐> test(t) || other.test(t);
      }
    
/*
之前的需求变更:
	 	定义一个方法,方法的参数传递一个字符串,传递两个Predicate接口
	 	1 字符串的长度是否大于5
 		2 字符串中是否包含a
 		满足一个条件即可
	 */
	public static boolean checkString(String str,Predicate<String> pre1,Predicate<String> pre2) {
//		return pre1.test(str) || pre2.test(str);
		return pre1.or(pre2).test(str);  //等价写法
	}
  • 03 默认方法:negate“非”(取反)
negate:
/* 	
 	需求:判断一个字符串,有两个判断的条件
 	1 字符串的长度是否大于5
 		大于则返回false
 		不大于返回true
 	
 	Preficate接口中有一个方法negate,表示非(取反)
 	default Predicate<T> negate() {
	 	return (t) ‐> ! test(t);
	}
 	
 */
public class D07Predicate4 {
	public static boolean checkString(String str,Predicate<String> pre1) {
//		return !pre1.test(str);  //!取反
		return pre1.negate().test(str);  //negate()取反 = 等价!
	}
	public static void main(String[] args) {
		String s = "abcdef";
		boolean b = checkString(s, (String str)->{
			return str.length()>5;
		});
		System.out.println(b);   //大于返回false
	}
	
}

练习:集合信息筛选

/*
 	需求:
		数组当中有多条“姓名+性别”的信息如下,请通过 Predicate 接口的拼装将符合要求的字符串筛选到集合
		ArrayList 中,需要同时满足两个条件:and
		1. 必须为女生;
		2. 姓名为4个字
 	
 */
public class D07Test {
	/*
	 	定义一个方法
	 	方法的参数传递一个包含人员信息的数组,两个Predicate接口,对数组中的信息进行过滤
	 	把满足条件的信息存到ArrayList集合并返回
	 */
	public static ArrayList<String> filter(String[] arr,Predicate<String> pre1,Predicate<String> pre2){
		ArrayList<String> list = new ArrayList<String>();
		for (String s : arr) {
			/*写法不对,思路差不多
			String name = s.split(",")[0];
			String sex = s.split(",")[1];
			boolean b = pre1.test(name) && pre1.test(sex);
			*/
			boolean b = pre1.and(pre2).test(s);
			if(b) {
				//两个条件都满足,把信息存储到ArrayList中
				list.add(s);
			}
		}
		return list;
	}
	public static void main(String[] args) {
		String[] arr = {"赵丽颖,18","迪丽热巴,女","古力娜扎,女","马尔扎哈,男"};
		//调用filter,参数传递数组和两个Lambda
		ArrayList<String> list = filter(arr, (String s)->{
			//获取姓名,判断位数
			return s.split(",")[0].length()==4;
		}, (String s)->{
			//判断性别是否为女
			return s.split(",")[1].equals("女");
		});
		//遍历集合
		for (String s : list) {
			System.out.println(s);
		}
	}
}

  1. java.util.function. Function 接口
  • java.util.function.Function<T,R> 接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后者称为后置条件。

    01 抽象方法: R apply(T t),根据类型T的参数获取类型R的结果。

//使用的场景例如:将 String 类型转换为 Integer 类型

public class D08Function {
	/*
	 	定义一个方法
	 	方法的参数传递一个字符串类型的整数
	 	方法的参数传递一个Function接口,泛型使用<String,Integer>
	 	使用Function接口中的方法apply,把字符串类型的整数,转换为Integer类型的整数
	 */
	public static void change(String s,Function<String, Integer> fun) {
		int in = fun.apply(s);  //自动拆箱,把Integer转换为int
		System.out.println(in);
	}
	public static void main(String[] args) {
		String s = "123";
		//调用方法,传递字符串类型整数和Lambda表达式
		change(s, (String str)->{
			return Integer.parseInt(str); //实现将字符串转换为整数
		});
		//优化
		change(s, str->Integer.parseInt(str));
	}
}

02 抽象方法: andThen,用来进行组合操作

 /*	
 	需求:
 		把String类型的字符串“123”转换成Integer类型,再把转换后的结果+10
 		把增加之后的Integer类型数据转换为String类型
 		
 	分析:
 		1 第一次把把String类型转换成Integer类型 ---  Function<String,Integer> fun1
 			Integer i = fun1.apply("123") + 10;
 		2 第二次把Integer类型数据转换为String类型 ---  Function<Integer,String> fun2
 	我们可以使用andThen方法把两次转换组合在一起
 		String s = fun1.andThen(fun2).apply("123");
 */
public class D08Function2 {
	public static void change(String s,Function<String,Integer> fun1,Function<Integer, String> fun2) {
		String ss = fun1.andThen(fun2).apply(s);  //处理同一份数据
		System.out.println(ss); //133
	}
	public static void main(String[] args) {
		String s = "123";
		change(s, (String str)->{
			//把字符串转换为整数
			return Integer.parseInt(str)+10;
		}, (Integer in)->{
			//把整数转换为字符串
			return in +"";
		});
		
		//优化:
		change(s, str->Integer.parseInt(str)+10,in->in +"");	
	}
}

03 练习:自定义函数模型拼接
需求:请使用 Function 进行函数模型的拼接,按照顺序需要执行的多个函数操作为:String str = “赵丽颖,20”;

  1. 将字符串截取数字年龄部分,得到字符串;
  2. 将上一步的字符串转换成为int类型的数字;
  3. 将上一步的int数字累加100,得到结果int数字
/*
	 练习:自定义函数模型拼接
		需求:请使用 Function 进行函数模型的拼接,按照顺序需要执行的多个函数操作为:String str = "赵丽颖,20";
		1. 将字符串截取数字年龄部分,得到字符串;	 "赵丽颖,20" --> "20"
		2. 将上一步的字符串转换成为int类型的数字;	"20" --> 20
		3. 将上一步的int数字累加100,得到结果int数字   20+100
 */
public class D08Test {
	public static int change(String s,Function<String,String> fun1,
		Function<String, Integer> fun2,Function<Integer, Integer> fun3) {
		return fun1.andThen(fun2).andThen(fun3).apply(s);
	}
	
	public static void main(String[] args) {
		String s = "赵丽丽,20";
		//调用change,参数传递字符串和三个Lambda表达式
		int num = change(s, (String str)->{
			return s.split(",")[1];  // "赵丽颖,20" --> "20"
		}, (String str)->{
			return Integer.parseInt(str); //"20" --> 20
		}, (Integer in)->{
			return in+100;  //20+100
		});
		System.out.println(num);  //120
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值