Java基础二十二:函数式接口介绍,函数式接口作为方法参数、返回值,Supplier接口、Consumer接口、Predicate接口、Function接口基本介绍及其案例小练习
函数式接口
1、 函数式接口概念及基本使用
1、函数式接口:有且仅有一个抽象方法的接口,函数式接口就是Lambda表达式使用的前提
2、 Java中的函数式编程体现的就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口,
只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导
注:@FunctionalInterface 在接口上加上这个注解就表达该接口是函数式接口
public class MyInterfaceDemo {
public static void main(String[] args) {
//函数式接口做为局部变量时,可以把Lambda表达式赋值给它
MyInterFace my = ()-> System.out.println("函数式接口");
my.show();
}
}
//加上这个注解,就表示它是函数式接口,在到里面添加一个抽象方法,注解就会报错
@FunctionalInterface
public interface MyInterFace {
void show();
}
2、函数式接口做为方法参数
需求:
1. 定义一个类(RunnableDemo),在类中提供两个方法
2. 一个方法是:startThread(Runnable r),方法参数Runnable是一个函数式接口
3. 一个方法是主方法,在主方法中调用startThread方法
4. 如果方法的参数是一个函数式接口,我们可以使用Lambda表达式作为参数传递
例如:StartThread(() -> System.out.println(Thread.currentThread().getName()+”线程启动了”))
public class RunnableDemo {
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()+"线程启动了!");
});
}
//Runnable为函数式接口,Ctrl+B可以查看源码
public static void startThread(Runnable r){
new Thread(r).start();//开启一个线程
}
}
3、 函数式接口作为方法的返回值
如果方法的返回值是一个函数式接口,可以使用Lambda表达式作为结果返回
例如:private static Comparator<String> getComparator(){
Return(s1,s2) -> s1.length() - s2.length();
}
/*需求:
1.定义一个类ComparatorDemo,在类中提供两个方法
2.一个方法是:Comparator<String> getComparator()方法返回值Comparator是一个函数式接口
3.一个方法是主方法,在主方法中调用getComparator()方法
* */
public class ComparatorDemo {
public static void main(String[] args) {
//构造使用场景
//定义集合,存储字符串元素
ArrayList<String> arr = new ArrayList<String>();
arr.add("aaaaa");
arr.add("ccc");
arr.add("bbbbbb");
arr.add("ddd");
System.out.println("排序前"+arr);
//Collections.sort(arr);//r如果只是传递arr这个集合参数,就是按照自然顺序进行排序
//System.out.println("排序后"+arr);
//使用Comparator<String>比较器排序
Collections.sort(arr,getComparator());//按照字母顺序,及字符长度进行排序
System.out.println("排序后"+arr);
}
//Comparator<String>比较器排序类的接口,返回的是该接口的实现类对象
private static Comparator<String> getComparator(){
//第一种:匿名内部类的方式(原始方式)
/*Comparator<String> comp = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length()-s2.length();
}
};*/
//第一种:匿名内部类的方式(改进方式)
/*return new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length()-s2.length();
}
};*/
//第二种:Lambda表达式
return(String s1,String s2)->{
return s1.length()-s2.length();
};
}
}
4、 常用的函数式接口(Supplier接口)
Java8在java.util.function包下预定义了大量的函数式接口提供给我们使用
重点学习下面4个接口:Supplier接口、Consumer接口、Predicate接口、Function接口
Supplier<T>包含一个无参的方法:
1、T get() :获得结果
2、该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据
3、Supplier<T>接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用
//Supplier接口基本使用
public class SupplierDemo {
public static void main(String[] args) {
//Lambda表达式方式,获取一个字符串数据
String s = getString(()->{
return "中国北京";
});
System.out.println(s);
//Lambda表达式方式,获取一个整数数据
Integer i = getInter(()->{
return 30;
});
System.out.println(i);
}
//定义一个方法,返回一个字符串数据
private static String getString(Supplier<String> sup){
return sup.get();
}
//定义一个方法,返回一个整数数据
private static Integer getInter(Supplier<Integer> sup){
return sup.get();
}
}
5、Supplier小练习
/*练习:
1、定义一个类SupplierTest,在类中提供两个方法
2、一个方法是:int getMax(Supplier<Integer> sup),用于返回一个int数组中的最大值
3、一个方法是主方法,在主方法中调用getMax方法
* */
public class SupplierTest {
public static void main(String[] args) {
//定义一个数组
int[] arr = {12,23,21,34,54,65};
//Lambda表达式的方式,返回值是一个int类型
int maxValue = getMax(()->{
int max =0;
for(int x=1;x<arr.length;x++){
if(arr[x] > max){
max = arr[x];
}
}
return max;
});
System.out.println(maxValue);
}
//用于返回一个int数组中的最大值
private static int getMax(Supplier<Integer> sup){
return sup.get();
}
}
6、常用的函数式接口(Consumer接口)
//Consumer接口基本操作
public class ConsumerDemo {
public static void main(String[] args) {
//第一种:Lambda表达式
operatorString("中国北京",(String s)->{
System.out.println(s);
});
/*第二种:方法引用
operatorString("中国北京",System.out::println);*/
//第三种方式:对字符串反转后再转成字符串进行输出
operatorString("中国北京",(String s)->{
System.out.println(new StringBuilder(s).reverse().toString());
});
System.out.println("------------------------");
//调用2次消费的方法
operatorString("中国北京",(String s)->
System.out.println(s),(String s) ->System.out.println(new StringBuilder(s).reverse().toString())
);
}
//定义一个方法,消费一个字符串数据
private static void operatorString(String name, Consumer<String> con){
con.accept(name);
}
//定义一个方法,用不同的方式消费一个字符串数据两次
private static void operatorString(String name, Consumer<String> con1,Consumer<String> con2){
/*con1.accept(name);
con2.accept(name);*/
//对上面两句改进优化
con1.andThen(con2).accept(name);
}
}
7、Consumer接口小练习
//Consumer小练习
public class ConsumerDemo2 {
public static void main(String[] args) {
String[] strArray = {"浙江杭州,20","江苏南京,30","广东深圳,40"};
pringtInfo(strArray,(String str)->{
String name = str.split(",")[0];
System.out.print("姓名"+name);
},(String str)->{
int age = Integer.parseInt(str.split(",")[1]);
System.out.println(",年龄"+age);
} );
}
private static void pringtInfo(String[] strArray, Consumer<String> con1,Consumer<String> con2){
for(String str: strArray){
con1.andThen(con2).accept(str);
}
}
}
8、常用的函数式接口(Predicate接口)
//Predicate接口test、negate方法
public class PrediccateDemo1 {
public static void main(String[] args) {
//判断hello这个字符串的长度是否大于8
boolean b1 = checkString("hello",(String s)->{
return s.length()>8;
});
System.out.println(b1);
}
//判断给定的字符串是否满足要求
private static boolean checkString(String s, Predicate<String> pre){
//return pre.test(s);
return pre.negate().test(s); //对结果取反
}
}
//Predicate接口的add、or方法
public class PredicateDemo2 {
public static void main(String[] args) {
boolean b3 = checkString("hello",(String s)->s.length()>8,s -> s.length()<15);
System.out.println(b3);
}
//同一个字符串给出两个不同的判断条件,最后把这两个判断的结果做逻辑与运算的结果作为最终的结果
private static boolean checkString(String s, Predicate<String> pre1,Predicate<String> pre2){
/*boolean b1 = pre1.test(s);
boolean b2 = pre2.test(s);
boolean b = b1 && b2;
return b;*/
//add方法对上面的代码进行优化
//return pre1.and(pre2).test(s);
//or方法
return pre1.or(pre2).test(s);
}
}
9、Predicate接口小练习
//Predicate小练习
public class PredicateDemo3 {
public static void main(String[] args) {
String[] arrString = {"浙江杭州,30","西安,31","深圳,33","四川成都,34"};
ArrayList<String> array = myFilter(arrString,s->s.split(",")[0].length()>2,
s->Integer.parseInt(s.split(",")[1])>33);
for(String str: array){
System.out.println(str);
}
}
//通过Predicate接口拼装,将符合要求的字符串筛选到集合中
private static ArrayList<String> myFilter(String[] strArray, Predicate<String> pre1, Predicate<String> pre2){
//定义一个集合
ArrayList<String> array = new ArrayList<String>();
//遍历数组
for(String str:strArray){
if(pre1.and(pre2).test(str)){
array.add(str);
}
}
return array;
}
}
10、常用的函数式接口(Function接口)
//Function接口的2个方法的基本使用
public class FunctionDemo {
public static void main(String[] args) {
//第一种:Lambda表达式调用第一个方法
convery("100",(String s)->{
return Integer.parseInt(s);
});
//第二种:方法引用调用第一个方法
convery("100",Integer::parseInt);
//Lambda表达式调用第二个方法
convery1(100,(Integer i)->{
return String.valueOf(i+500);
});
//Lambda表达式调用第三个方法
convery2("100",(String s)->{
return Integer.parseInt(s);
},(Integer i)->{
return String.valueOf(i+500);
});
}
//定义一个方法,把字符串转换为int类型,在控制台输出
private static void convery(String s, Function<String,Integer> fun){
//Integer i = fun.apply(s);
int i = fun.apply(s); //Integer和int类型接收都可以
System.out.println(i);
}
//把一个int类型的数据加上一个整数过后,转换为字符串在控制台输出
private static void convery1(Integer i,Function<Integer,String> fun){
String s = fun.apply(i);
System.out.println(s);
}
//把一个字符串转换为int类型,把int类型加上一个整数过后,转换为字符串在控制台输出
private static void convery2(String s,Function<String,Integer> fun1,Function<Integer,String> fun2){
/*Integer i = fun1.apply(s);
String ss = fun2.apply(i);
System.out.println(ss);*/
//对上面代码进行优化
String ss = fun1.andThen(fun2).apply(s);
System.out.println(ss);
}
}
11、Function接口小练习
//Function接口小练习
public class FunctionDemo1 {
public static void main(String[] args) {
String s = "中国北京,30";
/*convert(s,(String ss)->{
return s.split(",")[1];
},(String ss)->{
return Integer.parseInt(ss);
},(Integer i)->{
return i+70;
});*/
//对上面代码进行优化
convert(s,ss->s.split(",")[1],ss->Integer.parseInt(ss),i->i+70);
}
private static void convert(String s, Function<String,String> fun1, Function<String,Integer> fun2,Function<Integer,Integer> fun3){
Integer i = fun1.andThen(fun2).andThen(fun3).apply(s);
System.out.println(i);
}
}
Java基础二十二:函数式接口介绍,函数式接口作为方法参数、返回值,Supplier接口、Consumer接口、Predicate接口、Function接口基本介绍及其案例小练习相关推荐
- 【Java 进阶】匿名类(代码传递、回调、过滤器)、Lambda表达式(方法引用)、函数式接口(Supplier、Consumer、Predicate、Function)
匿名类 匿名类(Anonymous Class) 匿名类的使用注意 匿名类 - 代码传递 - 测试代码运行时间的工具类 匿名类 - 回调 - 简易网络请求 匿名类 - 过滤器 - 获取目录下的所有文件 ...
- Java基础(十二)
合成设计模式的引出 引用传递实际应用 案例一(类关联结构) 有的人有一辆汽车,有些人坐公交:要求通过面向对象的设计来解决实现以上的这种关系转换. class Car{private String na ...
- Java基础语法十二 泛型程序设计
1 意义 泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用. 常见应用 : ArrayList 2 K T V E ? object等的含义 类型变量使用大写形式 E – Element ( ...
- 重学java基础第二十二课:IDEA安装
- 重学java基础第十二课:计算机语言发展史
- 二十六、设置时序电路初始状态的方法(初始值设置)(时序电路置数)
---------------------------------------------------------------------------------------------------- ...
- 阶段1 语言基础+高级_1-2 -面向对象和封装_11使用对象类型作为方法的返回值
自定义的类做为方法的返回值.新建类Dmeo05 谁调用我,我就把one的地址返回给谁 内存中发生了什么 程序要想运行main方法先进栈 进来以后定义了一个phone two.two和刚才有什么不一样? ...
- Java基础知识(二)(Object类的常用方法、日期时间类、System类、StringBuilder类、包装类、Collection集合、Iterator迭代器、泛型、list集Set接口...)
文章目录 Java基础知识(二) 1.Object类的常用方法 1.1 toString方法 1.2 equals方法 1.3 Objects类 2.日期时间类 2.1 Date类 2.2 DateF ...
- JAVA基础知识总结:一到二十二全部总结
>一: 一.软件开发的常识 1.什么是软件? 一系列按照特定顺序组织起来的计算机数据或者指令 常见的软件: 系统软件:Windows\Mac OS \Linux 应用软件:QQ,一系列的播放器( ...
最新文章
- 【springboot基础】配置日志输出级别以及输出位置
- Tomcat的安装及配置。
- 1024程序员:算法仓鼠创业
- 腾讯想拿到Big Data资源,8h删抓紧时间!!
- Android的启动方式
- Windows系统字体和系统应用字体
- 游戏开发中的那点英语
- HYSPLIT简明教程
- 数据结构与算法面试题80道
- unity 更换standard shader
- 生活小常识,哪些药物不能混合用?
- 财源滚滚的第三方支付牌照
- 影视动画专业有木有c语言,那些头秃的专业,不了解一下?
- 微信会员卡自定义code模式--从创建到激活
- endnote使用方法大全,endnote教程
- 计算机工程学院团总支学生会,凝聚团队力量,展现青春活力——计算机工程学院团总支学生会开展学生干部素质拓展活动...
- c语言中int和void,关于指针:void(*)void和int(*)int在C中的含义是什么?
- 如何压缩图片jpg大小?怎么缩小jpg大小kb?
- 协议 驱动 接口 服务器,TCP/IP 协议底层驱动原理 (含网卡芯片读写) 说明 [撸 swoole 和 workerman 的同学建议瞧瞧]...
- 编程萌新必看!初学C语言必会的知识点,你学废了吗?