目录

  1.0 何为Lambda

  1.1 Lambda语法特征

  1.2 Lambda实例

  1.3 Lambda中的stream

  1.4 Lambda 中的 stream 效率

1.0 何为Lambda

  所谓 “Lambda 表达式”(lambda expression)它是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。如果想深入可以去这位仁兄的博客看看 点我进去 这里做个了解。

1.1 Lambda语法特征

  认准  " - > "  Lambad 老字号

  可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。   

  可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。

  可选的大括号:如果主体包含了一个语句,就不需要使用大括号。 

  可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

    在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

 String first = "";
Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length()); //编译会出错

1.2 Lambda实例

  从语法特征分析出的傻白甜代码片段

// 1. 不需要参数,返回值为 5
() -> 5 // 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x // 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y // 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)

 

 从代码片段写出的傻白甜代码  来源于 菜鸟教程 我进去

public class Java8Tester {
public static void main(String args[]){
Java8Tester tester = new Java8Tester(); // 类型声明
MathOperation addition = (int a, int b) -> a + b; // 不用类型声明
MathOperation subtraction = (a, b) -> a - b; // 大括号中的返回语句
MathOperation multiplication = (int a, int b) -> { return a * b; }; // 没有大括号及返回语句
MathOperation division = (int a, int b) -> a / b; System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
System.out.println("10 / 5 = " + tester.operate(10, 5, division)); // 不用括号
GreetingService greetService1 = message ->
System.out.println("Hello " + message); // 用括号
GreetingService greetService2 = (message) ->
System.out.println("Hello " + message); greetService1.sayMessage("Runoob");
greetService2.sayMessage("Google");
} interface MathOperation {
int operation(int a, int b);
} interface GreetingService {
void sayMessage(String message);
} private int operate(int a, int b, MathOperation mathOperation){
return mathOperation.operation(a, b);
}
}

Lambda表达式应用场景

  使用 ( ) - { } 来代替匿名类  代码来自这位仁兄 点我进去

//未使用Lambda
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("no use lambda");
}
});
//使用之后
Thread t2 = new Thread(() -> System.out.println("use lambda"));

我们看到相对而言Lambda表达式要比匿名类要优雅简洁很多~。

  以流水线的方式处理数据

List<Integer> integers = Arrays.asList(4, 5, 6,1, 2, 3,7, 8,8,9,10);

List<Integer> evens = integers.stream().filter(i -> i % 2 == 0)
.collect(Collectors.toList()); //过滤出偶数列表 [4,6,8,8,10]<br>
List<Integer> sortIntegers = integers.stream().sorted()
.limit(5).collect(Collectors.toList());//排序并且提取出前5个元素 [1,2,3,4,5] List<Integer> squareList = integers.stream().map(i -> i * i).collect(Collectors.toList());//转成平方列表 int sum = integers.stream().mapToInt(Integer::intValue).sum();//求和 Set<Integer> integersSet = integers.stream().collect(Collectors.toSet());//转成其它数据结构比如set Map<Boolean, List<Integer>> listMap = integers.stream().collect(Collectors.groupingBy(i -> i % 2 == 0)); //根据奇偶性分组 List<Integer> list = integers.stream().filter(i -> i % 2 == 0).map(i -> i * i).distinct().collect(Collectors.toList());//复合操作

1.3 Lambda表达式中的Stream

  在java 8 中 Stream 不是集合元素,它不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream 的并行操作依赖于 Java7 中引入的 Fork/Join 框架(JSR166y)来拆分任务和加速处理过程。

   甚至函数 由值创建流:

Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action");

      由数组创建流:

int[] numbers = {2, 3, 5, 7, 11, 13}; int sum = Arrays.stream(numbers).sum();  

 用内部迭代取代外部迭代

    外部迭代:描述怎么干,代码里嵌套2个以上的for循环的都比较难读懂;只能顺序处理List中的元素;

    内部迭代:描述要干什么,而不是怎么干;不一定需要顺序处理List中的元素

List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
for (String feature : features) {
System.out.println(feature); //外部迭代
} List features = Arrays.asList("Lambdas", "Default Method", "Stream API",
"Date and Time API");
features.stream.forEach(n -> System.out.println(n)); //内部迭代

1.4 Lambda 中的 stream 效率

Lambda的并行流虽好,但也要注意使用场景。如果平常的业务处理比如过滤,提取数据,没有涉及特别大的数据和耗时操作,则真的不需要开启并行流。我在工作中看到有些人一个只有几十个元素的列表的过滤操作也开启了并行流,其实这样做会更慢。因为多行线程的开启和同步这些花费的时间往往比你真实的处理时间要多很多。但一些耗时的操作比如I/O访问,DB查询,远程调用,这些如果可以并行的话,则开启并行流是可提升很大性能的。因为并行流的底层原理是fork/join,如果你的数据分块不是很好切分,也不建议开启并行流。举个例子ArrayList的Stream可以开启并行流,而LinkedList则不建议,因为LinkedList每次做数据切分要遍历整个链表,这本身就已经很浪费性能,而ArrayList则不会。

有篇来自 发布在 jaxenter 的调查报告 《How misusing Streams can make your code 5 times slower》

原文地址点我进去  中文翻译版 点我进去  此文用代码实验得出了一个结论 如果你要进行stream操作 使用 iterators and for-each 效率更高

解问 lambda表达式的更多相关文章

  1. 【Java学习笔记之三十一】详解Java8 lambda表达式

    Java 8 发布日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Java 8之前 ...

  2. java8函数式接口详解、函数接口详解、lambda表达式匿名函数、方法引用使用含义、函数式接口实例、如何定义函数式接口

    函数式接口详细定义 函数式接口只有一个抽象方法 由于default方法有一个实现,所以他们不是抽象的. 如果一个接口定义了一个抽象方法,而他恰好覆盖了Object的public方法,仍旧不算做接口的抽 ...

  3. Lambda表达式常用代码示例

    Lambda表达式常用代码示例 2017-10-24 目录 1 Lambda表达式是什么2 Lambda表达式语法3 函数式接口是什么  3.1 常用函数式接口4 Lambdas和Streams结合使 ...

  4. Java8特性详解 lambda表达式 Stream

    1.lambda表达式 Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正 ...

  5. Lambda表达式详解(例子详解)(转自:http://blog.csdn.net/damon316/article/details/51734661)

    Lambda表达式详解(例子详解)     lambda简介 lambda运算符:所有的lambda表达式都是用新的lambda运算符 " => ",可以叫他,“转到”或者 ...

  6. lambda表达式,filter,map,reduce,curry,打包与解包和

    当然是函数式那一套黑魔法啦,且听我细细道来. lambda表达式 也就是匿名函数. 用法:lambda 参数列表 : 返回值 例: +1函数 f=lambda x:x+1 max函数(条件语句的写法如 ...

  7. Python解包参数列表及 Lambda 表达式

    解包参数列表 当参数已经在python列表或元组中但需要为需要单独位置参数的函数调用解包时,会发生相反的情况.例如,内置的 range() 函数需要单独的 start 和 stop 参数.如果它们不能 ...

  8. Java 8 Lambda 表达式详解

    一.Java 8 Lambda 表达式了解 参考:Java 8 Lambda 表达式 | 菜鸟教程 1.1 介绍: Lambda 表达式,也可称为闭包,是推动 Java 8 发布的最重要新特性. La ...

  9. 类型:.net;问题:C#lambda表达式;结果:Lambda表达式详解

    Lambda表达式详解   前言 1.天真热,程序员活着不易,星期天,也要顶着火辣辣的太阳,总结这些东西. 2.夸夸lambda吧:简化了匿名委托的使用,让你让代码更加简洁,优雅.据说它是微软自c#1 ...

随机推荐

  1. [转载]jsonp详解

    http://www.cnblogs.com/lemontea/archive/2012/12/11/2812268.html json相信大家都用的多,jsonp我就一直没有机会用到,但也经常看到, ...

  2. CSS中的选择器(笔记)

    1.通配符选择器(*):通配符选择器是用来选择所有元素,也可以选择某个元素下的所有元素.所有浏览器都支持通配符选择器. ;;} .dome *{padding: 2px;} 2.元素选择器(Ele): ...

  3. Sparse Filtering简介

    当前很多的特征学习(feature learning)算法需要很多的超参数(hyper-parameter)调节, Sparse Filtering则只需要一个超参数--需要学习的特征的个数, 所以非 ...

  4. 可视化爬虫Portia安装和部署踩过的坑

    背景 Scrapy爬虫的确是好使好用,去过scrapinghub的官网浏览一下,更是赞叹可视化爬虫的犀利.scrapinghub有一系列的产品,开源了大部分项目,Portia负责可视化爬虫的编辑,Sp ...

  5. c++中引用的用法(转)

    from here 对于习惯使用C进行开发的朋友们,在看到c++中出现的&符号,可能会犯迷糊,因为在C语言中这个符号表示了取地址符,但是在C++中它却有着不同的用途,掌握C++的&符号 ...

  6. 差分约束系统+输出路径(I - Advertisement POJ - 1752 )

    题目链接:https://cn.vjudge.net/contest/276233#problem/I 题目大意:输入k和n,然后输入n行,每一次输入两个数,代表开端和结尾,如果这个区间内点的个数大于 ...

  7. F - Number of Connected Components UVALive - 7638 (并查集 + 思维)

    题目链接:https://cn.vjudge.net/contest/275589#problem/F 题目大意:就是给你n个数,如果说两个数之间的gcd!=1,那么就将这两个点连起来,问你最终这些点 ...

  8. 线段树区间更新(set暴力)

    题目链接:https://cn.vjudge.net/contest/66989#problem/I 具体思路:使用栈存储村庄被损坏的顺序,然后set存的是被损坏的村庄,然后每一次查询,直接找到要查询 ...

  9. VUE和ES6资源收集

    MDN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript https://developer.mozilla.org/en/docs/We ...

  10. 【codeforces】【比赛题解】#937 CF Round #467 (Div. 2)

    没有参加,但是之后几天打了哦,第三场AK的CF比赛. CF大扫荡计划正在稳步进行. [A]Olympiad 题意: 给\(n\)个人颁奖,要满足: 至少有一个人拿奖. 如果得分为\(x\)的有奖,那么 ...