当前位置:网站首页>函数式接口和方法引用
函数式接口和方法引用
2022-07-02 07:35:00 【Cold Snowflakes】
Lambda表达式描述的是,接口中那个抽象方法要做的事情。
实际Lambda本质是,实现了那个接口的一个类的对象。
接口的组成
常量:默认是 public static final
方法:默认是 public abstract
在JAVA8中,增加了默认方法(public default),静态方法(public static)
在JAVA9中,增加了私有方法
For Instance
public interface eatable {
// 抽象方法 实现类 必须进行实现
void funAbstract();
// 默认方法 和 静态方法 都需要方法体
/** * 默认方法: 不强制实现类必须重写, 实现类可以直接使用 * 主要用于接口的升级,而不破坏现有的代码 */
default void funDefault(){
System.out.println("默认方法");
}
/** * 接口中的静态方法 只能被接口调用 */
static void funStatic(){
System.out.println("静态方法");
}
}
public static void main(String[] args) {
// 实现 抽象方法 并调用 默认方法
((eatable) () -> System.out.println("实现抽象方法")).funDefault();
// 实现 抽象方法 并调用 抽象方法
((eatable) () -> System.out.println("实现抽象方法")).funAbstract();
// 接口中的静态方法 只能被 接口调用, 不能被实现类调用
eatable.funStatic(); // OK
((eatable) () -> System.out.println("实现抽象方法")).funStatic(); // Error
}
方法引用(使用已有的方法逻辑去处理接口中的那个抽象方法)
引用 类中的 静态方法
// 抽象方法的参数 全部传递给 被引用的静态方法
public static void main(String[] args) {
((eatable) s -> Integer.parseInt(s)) // lambda 形式
.toInt("2349645");
((eatable) Integer::parseInt) // 类名::静态方法
.toInt("23");
}
interface eatable {
void toInt(String s);
}
引用 类中的 非静态方法
// 抽象方法的参数 全部传递给 被引用的非静态方法
public static void main(String[] args) {
((eatable)s -> System.out.println(s.toUpperCase()))
.toUpper("fdf");
((eatable)new linshi()::printString)
.toUpper("fsdf"); // 借助对象 , 引用类中的非静态方法
}
class linshi {
public void printString(String s){
System.out.println(s.toUpperCase());
}
}
interface eatable {
void toUpper(String s);
}
也可以这样:
但注意:接口中的那个抽象方法 第一个参数的参数类型 得是 linshi
,后面的参数传给了 printString
方法。
public static void main(String[] args) {
((eatable)(s,a) -> System.out.println(a.toUpperCase()))
.toUpper(new linshi(),"fgwerg");
/** * 使用这种 类名::非静态方法 形式的时候 * * 注意 接口中的那个抽象方法 第一个参数的参数类型 得是 linshi * 之后的参数 都传给 printString 方法 */
((eatable)linshi::printString)
.toUpper(new linshi(),"grg");
}
class linshi {
public void printString(String s){
System.out.println(s.toUpperCase());
}
}
interface eatable {
// 第一个参数 作为调用者
void toUpper(linshi a,String s); // 第二个参数 给到 printString 方法去作为参数
}
函数式接口
有且仅有一个抽象方法的接口,函数式接口就是 lambda 表达式的使用前提。
可以使用 @FunctionalInterface 进行标记 函数式接口。
使用函数式接口 作为参数时,可以传递过去一个 lambda 表达式。
public class lambdademo {
public static void main(String[] args) {
ArrayList<String> array = new ArrayList<>();
array.add("ccc");
array.add("aa");
array.add("b");
array.add("dddd");
System.out.println("排序前: " + array);
// Collections.sort(array); // 自然排序
Collections.sort(array,getComparator()); // 比较器排序
System.out.println("排序后: " + array);
}
private static Comparator<String> getComparator(){
// 匿名内部类方式
// return new Comparator<String>() {
// @Override
// public int compare(String s1, String s2) {
// return s1.length() - s2.length();
// }
// };
// lambda方式, 因为返回值是 函数式接口
return (s1,s2) -> s1.length() - s2.length();
}
}
常用函数式接口
Supplier接口
public static void main(String[] args) {
// 传一个 lambda ,实际上是 定义 抽象方法Supplier.get的逻辑
String string = getString(() -> "林青霞");
System.out.println(string);
}
// 这里设置接口泛型 为 String, 表示 get 方法 返回类型是 String
private static String getString(Supplier<String> sup){
return sup.get();
}
Consumer接口
public static void main(String[] args) {
// 第一个参数是 传过去的数据
// 第二个参数是 定义 抽象方法 accept的逻辑
getString("随便吧",System.out::print);
}
// 泛型 String 指定了 accept 的参数类型
private static void getString(String s, Consumer<String> cn){
// cn.accept(s);
Consumer<String> t = a -> System.out.print(a.length() + 1);
cn.andThen(t).accept(s);
// cn先执行一次 accept(s)
// t 再执行一次 accept(s)
}
Predicate接口
常用于判断参数是否满足指定条件
boolean test(T t) // 对给定参数进行判断, 判断逻辑由 lambda 提供
default Predicate<T> negate()
default Predicate<T> and(Predicate other)
default Predicate<T> or(Predicate other)
public static void main(String[] args) {
boolean res = checkString("fewef", s -> s.length() > 8);
System.out.print(res);
}
private static boolean checkString(String s, Predicate<String> t){
// return t.test(s);
// return t.negate().test(s); // 非
// return t.and(a -> a.startsWith("fy")).test(s); // 与
return t.or(a -> a.startsWith("fy")).test(s); // 或
}
边栏推荐
- 【AGC】构建服务3-认证服务示例
- 二叉树专题--P1030 [NOIP2001 普及组] 求先序排列
- MySQL keyword
- Overview of integrated learning
- Flink two Open, implement Batch Lookup join (attached source)
- 正则及常用公式
- Jsp webshell Free from killing - The Foundation of JSP
- Hdu1236 ranking (structure Sorting)
- 三.芯片启动和时钟系统
- Set the playback speed during the playback of UOB equipment
猜你喜欢
[applinking practical case] share in app pictures through applinking
华为应用市场应用统计数据问题大揭秘
【深入浅出玩转FPGA学习5-----复位设计】
二叉树专题--AcWing 1589. 构建二叉搜索树
QT learning diary 7 - qmainwindow
【深入浅出玩转FPGA学习3-----基本语法】
[play with FPGA learning 2 in simple terms ----- design skills (basic grammar)]
Special topic of binary tree -- acwing 1497 Traversal of the tree (use post and mid order traversal to build a binary tree)
2022爱分析· 国央企数字化厂商全景报告
Easyexcel, a concise, fast and memory saving excel processing tool
随机推荐
AppGallery Connect场景化开发实战—图片存储分享
Convert yv12 to rgb565 image conversion, with YUV to RGB test
[AGC] how to solve the problem that the local display of event analysis data is inconsistent with that in AGC panel?
2022-06-17
LVM操作
MongoDB 学习整理(条件操作符,$type 操作符,limit()方法,skip() 方法 和 sort() 方法)
JSP webshell free -- the basis of JSP
PCL eigen introduction and simple use
[quick application] there are many words in the text component. How to solve the problem that the div style next to it will be stretched
P1055 [NOIP2008 普及组] ISBN 号码
[play with FPGA learning 4 in simple terms ----- talk about state machine design]
首份中国企业敏捷实践白皮书发布| 附完整下载
【AGC】如何解决事件分析数据本地和AGC面板中显示不一致的问题?
Jsp webshell Free from killing - The Foundation of JSP
【付费推广】常见问题合集,推荐榜单FAQ
洛谷 P3398 仓鼠找 sugar(树上倍增 lca 判断树中两条路径是否相交 结论)
二叉树专题--【深基16.例7】普通二叉树(简化版)(multiset 求前驱 后继 哨兵法)
Special topic of binary tree -- acwing 3384 Binary tree traversal (known preorder traversal, while building a tree, while outputting middle order traversal)
力扣(LeetCode)182. 查找重复的电子邮箱(2022.07.01)
Filtering of PCL