1. 函数式接口

1.1 函数式接口概述

  

代码示例:

定义一个接口:

//次注解表示该接口为函数式接口,只能有一个抽象方法,如果有第二个就会报错。
@FunctionalInterface
public interface MyInterface {
void show();
}

定义测试类:

//函数式接口:有且仅有一个抽象方法的接口
public class MyInterfaceDemo {
public static void main(String[] args) {
MyInterface my = () -> System.out.println("函数式接口");
my.show();
}
}

运行结果:

  

1.2 函数式接口作为方法的参数

  

代码示例:

//定义一个类(RunnableDemo),在类中提供两个方法
//一个方法是: startThread(Runnable r)方法,参数Runnable是一个函数式接口(源码中以注解)
//一个方法是主方法,在主方法中调用startThread方法
public class RunnableDemo {
private static void startThread(Runnable r) {
new Thread(r).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() + "线程启动了"));
}

运行结果:

  

1.3 函数式接口作为方法的返回值

  

代码示例:

//定义一个类(ComparatorDemo),在类中提供两个方法
//一个方法是: Comparator<String> getComparator() 方法返 回值Comparator是一个函数式接口
//一个方法是主方法,在主方法中调用getComparator方法 public class ComparatorDemo {
private static Comparator<String> getComparator() {
// 匿名内部类,可以直接返回
// return new Comparator<String>() {
//
// @Override
// public int compare(String o1, String o2) {
// // 按照字符串的数量,从少到多排序
// return o1.length() - o2.length();
// }
// }; // Lambda表达式
return (s1, s2) -> s1.length() - s2.length(); } public static void main(String[] args) {
// 构造使用场景 // 定义集合,存储字符元素
ArrayList<String> array = new ArrayList<>(); array.add("cccc");
array.add("aaa");
array.add("b");
array.add("ddd"); System.out.println("排序前:" + array); // 这里使用我们自己定义的排序规则
Collections.sort(array, getComparator());
System.out.println("排序后:" + array); }
}

运行结果:

  

1.4 常用的函数式接口

  

1.5 Supplier接口

  

代码示例:

public class SupplierDemo {
public static void main(String[] args) {
//该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式实现)返回一个数据 String s = getString(() -> "林青霞");
System.out.println(s); Integer i = getInteger(() -> 30);
System.out.println(i);
} // 定义一个方法,返回一个整数数据
private static Integer getInteger(Supplier<Integer> sup) {
return sup.get(); } // 定义一个方法,返回一个字符串数据
private static String getString(Supplier<String> sup) {
return sup.get();
}
}

运行结果:

  

1.5.1 练习

  
代码示例:

//定义一个类(SupplierTest),在类中提供两个方法
//一个方法是: int getMax(Supplier<Integer> sup)
//用于返回一个int数组中的最大值
//一个方法是主方法,在主方法中调用getMax方法 public class SupplierTest {
// 返回一个int数组中的最大值
private static int getMax(Supplier<Integer> sup) {
return sup.get();
} public static void main(String[] args) {
// 定义一个int数组
int[] arr = { 13, 34, 56, 23 }; int maxValue = getMax(() -> {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
});
System.out.println(maxValue);
}
}

运行结果:

  

1.6 Consumer接口

  

代码示例:

public class ConsumerDemo {
public static void main(String[] args) {
// Lambda表达式
operatorString("林青霞", (String s) -> {
System.out.println(s);
}); // Lambda表达式简化 operatorString("林青霞", s -> System.out.println(s)); // 也可以使用引用方法
operatorString("林青霞", System.out::println); // 也可以操作字符串
operatorString("林青霞", s -> System.out.println(new StringBuilder(s).reverse().toString())); System.out.println("--------------------"); //操作两次String字符串
operatorString("林青霞", s -> System.out.println(s), s -> System.out.println(new StringBuilder(s).reverse().toString())); } // 定义一个方法,用不同的方式消费一个字符串数据两次
private static void operatorString(String name, Consumer<String> con1, Consumer<String> con2) {
con1.accept(name);
con2.accept(name);
} // 定义一个方法,消费一个字符串数据
private static void operatorString(String name, Consumer<String> con) {
con.accept(name);
}
}

运行结果:

  

1.6.1 练习

  
代码示例:

public class ConsumerTest {
public static void main(String[] args) {
String[] strArray = { "林青霞,30", "张曼玉,35", "王祖贤,33" }; // Lambda表达式
printInfo(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);
}));
System.out.println("--------------------");
// 简化Lambda表达式
printInfo(strArray, str -> System.out.print("姓名:" + str.split(",")[0]),
str -> System.out.println(",年龄:" + Integer.parseInt(str.split(",")[1]))); } private static void printInfo(String[] strArray, Consumer<String> con1, Consumer<String> con2) {
for (String str : strArray) {
// 将con1和con2组合到一起,然后操作
con1.andThen(con2).accept(str);
}
}
}

运行结果:

  

1.7 Predicate接口

  

代码示例:

tes(T t)t和negate()方法的使用:

public class PredicateDemo01 {
public static void main(String[] args) {
// checkString方法返回一个Boolean类型,直接接受即可
boolean b = checkString(("hello"), s -> s.length() > 5);
System.out.println(b);
} // 判断给定的字符串是否满足要求
private static boolean checkString(String s, Predicate<String> pre) {
return pre.test(s);
// 返回一个逻辑的否定,对应逻辑非,和test是相反的结果
//此操作和 return !pre.test(s):是一样的
// return pre.negate().test(s);
}
}

运行结果:

  

and(Predicate other)和or(Predicate other)方法;

and(Predicate other)方法的使用:

public class PredicateDemo02 {
public static void main(String[] args) {
boolean b1 = checkString("hello", s -> s.length() > 5, s -> s.length() < 10);
System.out.println(b1); boolean b2 = checkString("hello", s -> s.length() > 3, s -> s.length() < 10);
System.out.println(b2);
} // 同一个字符串给出两个不同的判断条件,最后把这两个判断的结果做逻辑与运算的结果作为最终的结果
private static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2) {
// default Predicate<T> and (Predicate other): 返回一个组合判断,对应短路与
return pre1.and(pre2).test(s);
}
}

运行结果:

  

or(Predicate other)方法的使用:

public class PredicateDemo02 {
public static void main(String[] args) {
boolean b1 = checkString("hello", s -> s.length() > 5, s -> s.length() < 4);
System.out.println(b1); boolean b2 = checkString("hello", s -> s.length() > 3, s -> s.length() < 10);
System.out.println(b2);
} // 同一个字符串给出两个不同的判断条件,最后把这两个判断的结果做逻辑与运算的结果作为最终的结果
private static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2) {
// default Predicate<T> or (Predicate other): 返回一个组合判断,对应短路或
return pre1.or(pre2).test(s);
}
}

运行结果:

  

1.7.1 练习

  
代码示例:

public class PredicateTest {
public static void main(String[] args) {
String[] strArray = { "林青霞,30", "柳岩,34", "张曼玉,35", "貂蝉,31", "王祖贤,33" }; //用ArrayList接收,pre1为判断姓名长度,pre2为判断年龄大小
ArrayList<String> array = myFilter(strArray, s -> s.split(",")[0].length() > 2,
s -> Integer.parseInt(s.split(",")[1]) > 33); for (String str : array) {
System.out.println(str);
}
} // 通过Predicate接口的拼装将符合要求的字符串筛选到集合ArrayList中
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;
}
}

运行结果:

  

1.8 Function接口

  

代码示例:

public class FunctionDemo {
public static void main(String[] args) { // Lambda表达式
// convert("100", (String s) -> {
// return Integer.parseInt(s);
// });
// 简化Lambda表达式
convert("100", s -> Integer.parseInt(s));
// 方法引用
// convert("100", Integer::parseInt); convert(100, i -> String.valueOf(i + 566)); convert("100", s -> Integer.parseInt(s), i -> String.valueOf(i + 566)); } // 定义一个方法,把一个字符串转换int类型,在控制台输出
private static void convert(String s, Function<String, Integer> fun) {
//R apply(T t):将此函数应用于给定的参数
int i = fun.apply(s);
System.out.println(i);
} // 定义一个方法,把一个int类型的数据加上一个整数之后,转为字符串在控制台输出
private static void convert(int i, Function<Integer, String> fun) {
String s = fun.apply(i);
System.out.println(s);
} // 定义一个方法,把一个字符串转换int类型,把int类型的数据加上一个整数之后,转为字符串在控制台输出
private static void convert(String s, Function<String, Integer> fun1, Function<Integer, String> fun2) {
Integer i = fun1.apply(s);
String ss = fun2.apply(i);
System.out.println(ss); //default <V> Function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
// String ss = fun1.andThen(fun2).apply(s);
// System.out.println(ss);
}
}

运行结果:

  

1.8.1 练习

  
代码示例:

//String s =”林青霞,30";
//请按照我指定的要求进行操作:
//1:将字符串截取得到数字年龄部分 fun1
//2:将上一步的年龄字符串转换成为int类型的数据; fun2
//3:将上一步的int数据加70,得到一个int结果,在控制台输出 fun3
//请通过Funct ion接口来实现函数拼接 public class FunctionTest {
public static void main(String[] args) {
String s = "林青霞,30";
// Lambda表达式
convert(s, (String ss) -> {
return s.split(",")[1];
}, (String ss) -> {
return Integer.parseInt(ss);
}, (Integer i) -> {
return i + 70;
});
// 简化Lambda表达式
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) {
// 也可以用int类型来接收
Integer i = fun1.andThen(fun2).andThen(fun3).apply(s);
System.out.println(i);
}
}

运行结果:

  

Java基础00-函数式接口33的更多相关文章

  1. Java基础-Collection子接口之List接口

    Java基础-Collection子接口之List接口 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们掌握了Collection接口的使用后,再来看看Collection接口中 ...

  2. 用好JAVA中的函数式接口,轻松从通用代码框架中剥离掉业务定制逻辑

    大家好,又见面了. 今天我们一起聊一聊JAVA中的函数式接口.那我们首先要知道啥是函数式接口.它和JAVA中普通的接口有啥区别?其实函数式接口也是一个Interface类,是一种比较特殊的接口类,这个 ...

  3. Java基础-通过POI接口处理xls

    Java基础-通过POI接口处理xls 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  4. Java基础-Collection子接口之Set接口

    Java基础-Collection子接口之Set接口 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 学习Collection接口时,记得Collection中可以存放重复元素,也可 ...

  5. 【Java 8】函数式接口(一)—— Functional Interface简介

    什么是函数式接口(Functional Interface) 其实之前在讲Lambda表达式的时候提到过,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法. 这种类型的接 ...

  6. 《Java基础——抽象与接口》

    Java基础--抽象与接口       一.抽象: 规则: 关键字 abstract 修饰的类称为抽象类. 子类通过关键字extends实现继承. 关键字 abstract 修饰的方法称为抽象方法,抽 ...

  7. Java基础学习总结(33)——Java8 十大新特性详解

    Java8 十大新特性详解 本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API ...

  8. 【Java 8】函数式接口(二)—— 四大函数接口介绍

    前言 Java8中函数接口有很多,大概有几十个吧,具体究竟是多少我也数不清,所以一开始看的时候感觉一脸懵逼,不过其实根本没那么复杂,毕竟不应该也没必要把一个东西设计的很复杂. 几个单词 在学习了解之前 ...

  9. Java 8 特性 —— 函数式接口

    函数式接口 概述:接口中只有一个抽象方法. 函数式接口,即适用于函数式编程场景的接口.而 Java 中的函数式编程体现就是 Lambda,所以函数式接口就是可以适用于 Lambda 使用的接口.只有确 ...

  10. Java 之 常用函数式接口

    JDK提供了大量常用的函数式接口以丰富Lambda的典型使用场景,它们主要在 java.util.function 包中被提供.下面是最简单的几个接口及使用示例. 一.Supplier 接口 java ...

随机推荐

  1. QT绘制简易表盘

    1.简介 最近学习了一下QT,熟悉了一段时间后发现它的功能还是挺强大的,同时也比较方便用户上手去使用.现在就基于最近学习的内容,实现一个简易的带指针旋转功能的表盘.文中表盘的实现是基于QT的QPain ...

  2. 深度学习Dropout技术分析

    深度学习Dropout技术分析 什么是Dropout? dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃.注意是暂时,对于随机梯度下降来说,由于是随机 ...

  3. NVIDIA DRIVE AGX开发工具包

    NVIDIA DRIVE AGX开发工具包 英伟达drive AGX开发工具包提供了开发生产级自主车辆(AV)所需的硬件.软件和示例应用程序.NVIDIA DRIVE AGX系统建立在汽车产品级芯片上 ...

  4. 【NX二次开发】Block UI 通过浏览选择文件

    属性说明 属性   类型   描述   常规           BlockID    String    控件ID    Enable    Logical    是否可操作    Group    ...

  5. 【SQLite】教程04-SQLite数据类型

    SQLite 存储类 每个存储在 SQLite 数据库中的值都具有以下存储类之一: 存储类 描述 NULL 值是一个 NULL 值. INTEGER 值是一个带符号的整数,根据值的大小存储在 1.2. ...

  6. H5播放需要解密的m3u8音频文件

    <audio ref="audio"></audio> import CryptoJS from "crypto-js"; import ...

  7. Redis分布式锁 (图解-秒懂-史上最全)

    文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...

  8. Nginx为什么快到根本停不下来?

    Nginx 是一个免费的,开源的,高性能的 HTTP 服务器和反向代理,以及 IMAP / POP3 代理服务器. 图片来自 Pexels Nginx 以其高性能,稳定性,丰富的功能,简单的配置和低资 ...

  9. 既然有 HTTP 请求,为什么还要用 RPC 调用?

    首先,实名赞扬题主的问题.这个问题非常好. 其次,实名反对各个上来就讲RPC好而HTTP不好的答案.因为,题主的观点非常对. HTTP协议,以其中的Restful规范为代表,其优势很大.它可读性好,且 ...

  10. Django-Auth模块之auth_user表

    一.Auth模块之auth_user表 在创建Django项目之后直接执行数据迁移命令会自动生成许多表. Django在启动之后就可以直接访问admin路由,需要输入用户名和密码,数据参考的就是aut ...