了解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. leetcode——Reverse Linked List II 选择链表中部分节点逆序(AC)

    Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given 1-> ...

  2. 通过 Microsoft iSCSI Software Target 提供存储服务

    软件下载地址: Microsoft iSCSI Software Target 3.3 下载完后成解压软件包如下: 安装官方的描述Target 端也就是服务端 只支持Windows Server 20 ...

  3. [WASM] Compile C Code into WebAssembly

    We use the C language instead of pure WAST to create a square root function using WASM Fiddle (https ...

  4. 一文看懂AI芯片竞争五大维度

    下一波大趋势和大红利从互联网+让位于人工智能+,已成业界共识.在AI的数据.算法和芯片之三剑客中,考虑到AI算法开源的发展趋势,数据与芯片将占据越来越重要的地位,而作为AI发展支柱的芯片更是AI业的竞 ...

  5. Android 利用an框架快速实现网络请求(含下载上传文件)

    作者:Bgwan链接:https://zhuanlan.zhihu.com/p/22573081来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. an框架的网络框架是完全 ...

  6. Avro基础 分类: C_OHTERS 2015-02-14 19:56 310人阅读 评论(0) 收藏

    一.Avro的基本功能 1.定义了数据模式文件的语法,一般使用json文件.以及一些数据基本类型与复杂类型. 2.定义了数据序列化到文件后的数据格式,此格式可供各种语言进行读取. 3.为部分语言定义了 ...

  7. Longest Increasing Subsequences(最长递增子序列)的两种DP实现

    一.本文内容 最长递增子序列的两种动态规划算法实现,O(n^2)及O(nlogn).     二.问题描述 最长递增子序列:给定一个序列,从该序列找出最长的 升序/递增 子序列. 特点:1.子序列不要 ...

  8. 数据类型总结——Boolean类型(布尔类型)

    相关文章 简书原文:https://www.jianshu.com/p/e5c75d4be636 数据类型总结——概述:https://www.cnblogs.com/shcrk/p/9266015. ...

  9. Lucene学习总结之六:Lucene打分公式的数学推导 2014-06-25 14:20 384人阅读 评论(0) 收藏

    在进行Lucene的搜索过程解析之前,有必要单独的一张把Lucene score公式的推导,各部分的意义阐述一下.因为Lucene的搜索过程,很重要的一个步骤就是逐步的计算各部分的分数. Lucene ...

  10. ORACLE会话数、连接数配置

    ORACLE会话数.连接数配置 ORACLE会话数.连接数配置 ORACLE的会话数和连接数参数配置 以sysdba身份登录 sqlplus sys/xxxx as sysdba; 查看最大连接数: ...