jdk 8 lambda表达式以及Predicate接口
了解lambda之前先了解下什么是函数式接口,函数式接口即接口里必须有一个抽象方法(抽象的方法只能有一个,可以有其他的用default修饰的方法以及从Object继承的方法)
jdk8里新增了一个@FunctionalInterface注解,这个注解标注此接口为函数式接口,但是并不是必须的,任何满足我上面所说的只有一个抽象方法的接口都可以称之为函数式接口,但是如果一个接口上标注了此注解,就必须满足上述条件

lambda表达式用来重写函数式接口中的那个抽象方法,lambda直接看做匿名抽象类,因为lambda可以对接口赋值
lambda表达式的语法包括3个部分:
1.参数列表(...) 如(String s,Integer i) () (s) 等,没有参数时就是(),只有一个参数时可以写成str,省略掉参数的小括号
2.箭头 ->
3.执行的代码 { },执行的代码只有一行时,可以省略大括号
4.需要注意的是lambda无法在其方法体中修改局部变量的值
lambda表达式整体看作一个某个接口的匿名类,lambda的参数,方法体是该匿名类的下唯一重写抽象方法的参数,方法体,lambda是对匿名类的简化
下面以创建线程为例
//匿名内部类创建线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类启动线程");
}
}).start(); //使用lambda表达式启动一个新的线程
//()对应run方法的参数
//->后面表示run的方法体
new Thread(()->System.out.println("使用lambda启动线程")).start();
来看下jedis中execute方法关于lambda的例子

从上图可以看到execute方法需要一个RedisCallBack,这是一个接口,内部只有一个抽象方法,虽然没有@FunctionalInterface注解,但这是一个抽象接口

唯一的抽象方法doInRedis需要一个RedisConnection参数,返回一个泛型参数,我们抽取下excute需要的关于语法的关键代码
execute((RedisCallback<List<Object>>) connection -> {
connection.openPipeline();
return xx;
});
connection -> {connection.openPipeline();return xx;}); connection是doInRedis的形参,{}中doInRedis的方法体,而connection前面的(RedisCallback<List<Object>>)是对lambda的类型说明(RedisCallback<T>)
下面再举一个Runnable接口的例子
/**
* lambda语法包括3个部分:
* (参数列表)->{方法体;}
* 只有一个参数时,()可以省略
* 方法体只有一行时可以省略{;}
* @author tele
*
*/
public class Demo1 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
//遍历list
list.forEach(i->System.out.println(i)); //>=可以直接判断符号
/* int a = 1;
int b = 2;
System.out.println(b>=a?"b>a":"b<a");*/ //匿名内部类创建线程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("匿名内部类启动线程");
}
}).start(); //使用lambda表达式启动一个新的线程
//()对应run方法的参数
//->后面表示run的方法体
new Thread(()->System.out.println("使用lambda启动线程")).start(); //如果要使用lambda来声明接口那么接口中只能有一个抽象方法
//因为函数接口是只有一个抽象方法的接口(抽象的方法只能有一个,可以有其他的用default修饰的方法) String s = "lambda test";
int i= 100;
MyInterface myInterface = (str,m)->{
//i++; 错误,无法对i的值进行修改
System.out.println(i);
System.out.println(str + " " + m);
return str+"----"+str;
};
String result = myInterface.test(s,0);
System.out.println(result); } //定义一个内部的函数式接口
static interface MyInterface {
//void test(String s,int i);
String test(String s,int i);
}
}
到这再次说明,lambda表达式是重写了接口中的抽象方法,包括第16行的代码把lambda表达式传入到foreach中,传入的lambda表达式实质是对Consumer接口的accept方法的重写
参数类型的省略是因为java的类型推断,编译器知道函数式接口中的那个抽象方法需要什么类型


下面结合Predicate接口再来深入了解下lambda表达式,这个接口主要用于断言,当然他是一个函数式接口,可以看到他的抽象方法是test(),所以我们写的lambda表达式就是重写test方法
注意这里用了泛型

先看filter方法,filter方法对list进行遍历,满足test()后进行输出,而test的方法体就是我们传入的lambda表达式,从这一点上看,使用lambda有点绕的地方就是按照以往的做法我们调用filter时出了传入list,另一个参数应该为Precidate类型,然而使用了lambda后,我们直接传入Predicate接口中的抽象方法的参数与方法体即可,即使我们传入一个Predicate类型的参数,接下来仍然是去调用test(),从这点看lambda可以说是一步到位了

完整代码,and对应&& or对应|| negate对应!
/**
* Predicate接口的使用
* @author tele
*
*/
public class Demo2 {
public static void main(String[] args) {
List<String> list = Arrays.asList("java","hadoop","python","php","lucene");
filter(list,s->s.startsWith("j"));//java
// filter(list, s->true);//全部输出 Predicate<String> condition1 = str->str.startsWith("j");
Predicate<String> condition2 = str->str.endsWith("h"); //and
Predicate<String> andCondition = condition1.and(condition2);
boolean result = andCondition.test("jsadh");
System.out.println(result);//true //or
Predicate<String> orCondition = condition1.or(condition2);
result = orCondition.test("jasd");
System.out.println(result);//true //negate,对判断条件取反
Predicate<String> negate = condition1.negate();
System.out.println(negate.test("aj"));//true //isEqual(了解,比较两个对象是否相等)
result = Predicate.isEqual("as").test("aaa");
System.out.println(result); } //test方法是predicate中的唯一一个抽象方法
public static void filter(List<String> list,Predicate<String> predicate) {
list.forEach(t->{
if(predicate.test(t)){
System.out.println(t);
}
});
}
}
jdk 8 lambda表达式以及Predicate接口的更多相关文章
- 009-jdk1.8版本新特性一-展方法,Lambda表达式,函数式接口、方法引用构造引用
一.JDK1.8 名称:Spider(蜘蛛) 发布日期:2014-03-18 新特性: 1.1.扩展方法[接口的默认方法] Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 defaul ...
- Lambda表达式和函数式接口
写在有道笔记中,链接地址.欢迎各位看官提出意见交流讨论 http://note.youdao.com/noteshare?id=147109f1bf7f3ae97c43d77891e6ebc8 Lam ...
- java8实战二------lambda表达式和函数式接口,简单就好
一.Lambda 可以把Lambda表达式理解为简洁地i表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表.函数主体.返回类型,可能还是一个可以抛出的异常列表. 听上去,跟我们用的匿名类,匿名 ...
- java8 Lambda 表达式和函数式接口快速理解
前言 接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Lambda 表达式和函数式接口说明. Lambda 表达式 lambda 表达式其实就是使用了 ...
- Java8 Lambda表达式、函数式接口和方法引用
目录 Java8 Lambda表达式和函数式接口 Lambda表达式 Lambda的使用 函数式接口FunctionalInterface Java内置四大核心函数式接口 方法引用 构造器引用 Jav ...
- Lambda表达式与函数式接口
Lambda表达式的类型,也被称为目标类型(targer type),Lambda表达式的目标类型必须是"函数式接口(functional interface)".函数式接口代表只 ...
- lambda表达式与函数接口的关系以及使用案例
lambda表达式与函数式接口是结合使用的. 函数式接口:接口中只有一个抽象方法的接口,其中可以包括default修饰,static 修饰的实例方法.函数式接口可以在接口上添加@FuncationIn ...
- Java8新特性(一)——Lambda表达式与函数式接口
一.Java8新特性概述 1.Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 接口中的默认方法与静态方法 6. 新时间日期 API 7. 其他新特 ...
- 还看不懂同事的代码?Lambda 表达式、函数接口了解一下
当前时间:2019年 11月 11日,距离 JDK 14 发布时间(2020年3月17日)还有多少天? // 距离JDK 14 发布还有多少天? LocalDate jdk14 = LocalDate ...
随机推荐
- BZOJ——3343: 教主的魔法 || 洛谷—— P2801 教主的魔法
http://www.lydsy.com/JudgeOnline/problem.php?id=3343 || https://www.luogu.org/problem/show?pid=280 ...
- jQuery的实现原理和核心
1.jQuery的实现原理 1)jQuery采用的是构造函数模式进行开发的,jQuery是一个类 2)上面说的常用的方法(CSS.属性.筛选.事件.动画.文档处理)都是定义在jQuery.protot ...
- 【Codeforces Round #431 (Div. 1) B】
[链接]h在这里写链接 [题意] 场上有 n 个点,它们分别向上与向右在不同时刻开始运动,相遇则改变移动方向,求最终这些点到达的坐标. [题解] 先把每个点的坐标都往它本该移动的方向相反的方向退ti个 ...
- [React Intl] Format Date and Time Using react-intl FormattedDate and FormattedTime
Using the react-intl FormattedDate and FormattedTime components, we’ll render a JavaScript Date into ...
- vue-cli 构建vue项目
师父说,咱们还是要用vue-cli 去构建前端项目.然后我就开始了 懵逼之旅. 今天上午主要就是搞懂用webpack和vue-cli怎么搭建 运行项目 首先找到了咱们博客园 园友的博客,提供了大概五个 ...
- mootools常用特性和示例(基础篇2)
接着上一篇:mootools常用特性和示例(基础篇1) 1.表单操作 html: <form id="myForm" action="submit.php" ...
- struts2漏洞原理及解决的方法
1.原理 Struts2的核心是使用的webwork框架,处理 action时通过调用底层的getter/setter方法来处理http的參数,它将每一个http參数声明为一个ONGL(这里是ONGL ...
- Internet连接共享只能上qq不能打开网页的问题解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 之前我写过一篇<Windows共享上网的做法>,在设置共享网络时是有一个家庭网络连接的选项的,如下图: 但 ...
- api接口安全以及https
一:加密方法: 1,对称加密 AES,3DES,DES等,适合做大量数据或数据文件的加解密. 2,非对称加密 如RSA,Rabin.公钥加密,私钥解密.对大数据量进行加解密时性能较低. 二:https ...
- Fragment的基本应用
转载请注明出处:http://blog.csdn.net/crazy1235/article/details/50933621 Fragment 还是先来基本介绍. Fragment –> 片段 ...