了解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接口的更多相关文章

  1. 009-jdk1.8版本新特性一-展方法,Lambda表达式,函数式接口、方法引用构造引用

    一.JDK1.8 名称:Spider(蜘蛛) 发布日期:2014-03-18 新特性: 1.1.扩展方法[接口的默认方法] Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 defaul ...

  2. Lambda表达式和函数式接口

    写在有道笔记中,链接地址.欢迎各位看官提出意见交流讨论 http://note.youdao.com/noteshare?id=147109f1bf7f3ae97c43d77891e6ebc8 Lam ...

  3. java8实战二------lambda表达式和函数式接口,简单就好

    一.Lambda 可以把Lambda表达式理解为简洁地i表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表.函数主体.返回类型,可能还是一个可以抛出的异常列表. 听上去,跟我们用的匿名类,匿名 ...

  4. java8 Lambda 表达式和函数式接口快速理解

    前言 接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Lambda 表达式和函数式接口说明. Lambda 表达式 lambda 表达式其实就是使用了 ...

  5. Java8 Lambda表达式、函数式接口和方法引用

    目录 Java8 Lambda表达式和函数式接口 Lambda表达式 Lambda的使用 函数式接口FunctionalInterface Java内置四大核心函数式接口 方法引用 构造器引用 Jav ...

  6. Lambda表达式与函数式接口

    Lambda表达式的类型,也被称为目标类型(targer type),Lambda表达式的目标类型必须是"函数式接口(functional interface)".函数式接口代表只 ...

  7. lambda表达式与函数接口的关系以及使用案例

    lambda表达式与函数式接口是结合使用的. 函数式接口:接口中只有一个抽象方法的接口,其中可以包括default修饰,static 修饰的实例方法.函数式接口可以在接口上添加@FuncationIn ...

  8. Java8新特性(一)——Lambda表达式与函数式接口

    一.Java8新特性概述 1.Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 接口中的默认方法与静态方法 6. 新时间日期 API 7. 其他新特 ...

  9. 还看不懂同事的代码?Lambda 表达式、函数接口了解一下

    当前时间:2019年 11月 11日,距离 JDK 14 发布时间(2020年3月17日)还有多少天? // 距离JDK 14 发布还有多少天? LocalDate jdk14 = LocalDate ...

随机推荐

  1. 语言模型(Language Modeling)与统计语言模型

    1. n-grams 统计语言模型研究的是一个单词序列出现的概率分布(probability distribution).例如对于英语,全体英文单词构成整个状态空间(state space). 边缘概 ...

  2. HDU 1166 敌兵布阵 树状数组||线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=1166 题目大意: 给定n个数的区间N<=50000,还有Q个询问(Q<=40000)求区间和. 每个 ...

  3. xcode 各种项目设置

    1:语言环境设置:项目–>PROJECT–>info–>Locailzation 2 : 手动加入项目依赖 Build Settings–>Search path–>Li ...

  4. JAVA一些基础概念

    Java (计算机编程语言) Java是一门面向对象编程语言,不仅吸收了C++语言的各种长处,还摒弃了C++里难以理解的多继承.指针等概念.因此Java语言具有功能强大和简单易用两个特征. Java语 ...

  5. Redis学习笔记(六)---List

    1.ArrayList与LinkList的区别 ArrayList的使用数组存入的方式,所以根据索引查询数据速度快,而增删元素是比较慢的,它需要将数据一位一位的移动,知道达到要求. LinkList使 ...

  6. Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument

    spring 5.+jpa 配置类出错: 十二月 20, 2018 5:53:01 下午 org.springframework.web.servlet.DispatcherServlet initS ...

  7. 【习题 5-14 UVA - 1598】Exchange

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 各组数据之间有空行! 且最后一行后面没有空行! 然后就是用set来模拟就好. 删除的时候,不着急删除. 因为并不用时刻输出集合大小. ...

  8. jQuery异步提交form表单

    使用jquery.form.js官网现在地址表单插件来实现异步form表单提交. 先看看官方的介绍: /* Usage Note: ----------- Do not use both ajaxSu ...

  9. php课程 1-3 web项目中php、html、js代码的执行顺序是怎样的(详解)

    php课程 1-3 web项目中php.html.js代码的执行顺序是怎样的(详解) 一.总结 一句话总结:b/s结构 总是先执行服务器端的先.js是客户端脚本 ,是最后执行的.所以肯定是php先执行 ...

  10. MySQLDump在使用之前一定要想到的事情

    MySQLDump经常用于迁移数据和备份. 下面创建实验数据,两个数据库和若干表create database db1 ;use db1;create table t1(id int primary ...