您的位置:首页 > 编程语言 > Java开发

JAVA8之lambda表达式详解,及stream中的lambda使用

2016-07-13 21:00 369 查看


lambda表达式详解


一.问题

1.什么是lambda表达式? 

2.lambda表达式用来干什么的? 

3.lambda表达式的优缺点? 

4.lambda表达式的使用场景? 

5.lambda只是一个语法糖吗?


二.概念

lambda表达式是JAVA8中提供的一种新的特性,它支持JAVA也能进行简单的“函数式编程”。 

它是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。


三.先看看效果

先看几个例子: 
1.使用lambda表达式实现Runnable
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.lambda;

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 使用lambda表达式替换Runnable匿名内部类
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> MingChenchen
*
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">RunableTest</span> {</span>
<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 普通的Runnable
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">runSomeThing</span>(){

Runnable runnable = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Runnable() {

<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">run</span>() {
System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I am running"</span>);
}
};
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Thread(runnable).start();
}

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 使用lambda后的
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">runSomeThingByLambda</span>(){
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Thread(() -> System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I am running"</span>)).start();
}

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) {
runSomeThing();
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//      runSomeThingByLambda();</span>
}
}

上述代码中:
() -> System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"I am running"</span>)就是一个lambda表达式,
可以看出,它是替代了<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Runnable(){}这个匿名内部类。
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li></ul>


2.使用lambda表达式实现Comparator
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.lambda;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.util.Arrays;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.util.Collections;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.util.Comparator;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.util.List;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">SortList</span> {</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//给入一个List</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> List<String> list =
Arrays.asList(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"my"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"name"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"is"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"uber"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"and"</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"uc"</span>);

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 对一个String的list进行排序 - 使用老方法
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">oldSort</span>(){
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//排序</span>
Collections.sort(list,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Comparator<String>() {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用新的排序规则 根据第二个字符进行逆序排</span>
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> <span class="hljs-title" style="box-sizing: border-box;">compare</span>(String a,String b){
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (a.charAt(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) <= b.charAt(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
}<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
}
}
});
}

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 新的排序方法 - 使用lambda表达式实现
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">newSort</span>(){
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//lambda会自动推断出 a,b 的类型</span>
Collections.sort(list, (a, b) -> a.charAt(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) < b.charAt(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) ? <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>:-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>);
}

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//      oldSort();</span>
newSort();
}
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li></ul>


3.使用lambda表达式实现ActionListener
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.lambda;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.awt.event.ActionEvent;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> java.awt.event.ActionListener;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> javax.swing.JButton;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ActionEventDemo</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> JButton button = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> JButton();

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">bindEvent</span>(){
button.addActionListener(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ActionListener() {
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">actionPerformed</span>(ActionEvent e) {
System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"你好!"</span> );

}
});
}

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 使用Lambda表达式 为button添加ActionListener
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">bindEventByLambda</span>(){
button.addActionListener(e -> System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"你好!"</span>));
}
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul>


四.来由

好了,通过上述的几个例子,大家差不多也能明白了lambda是用来干什么以及好处了。 

显而易见的,好处就是代码量大大减少了!程序逻辑也很清晰明了。 

它的用处浅显来说就是替代“内部匿名类”、可以对集合或者数组进行循环操作。

以前: 

面向对象式编程就应该纯粹的面向对象,于是经常看到这样的写法: 

如果你想写一个方法,那么就必须把它放到一个类里面,然后new出来对象,对象调用这个方法。 

匿名类型最大的问题就在于其冗余的语法。 

有人戏称匿名类型导致了“高度问题”(height problem): 

比如大多匿名内部类的多行代码中仅有一行在做实际工作。

因此JAVA8中就提供了这种“函数式编程”的方法 —— lambda表达式,供我们来更加简明扼要的实现内部匿名类的功能。


五.什么时候可以使用它?

先说一个名词的概念

函数式接口:Functional Interface. 

定义的一个接口,接口里面必须 有且只有一个抽象方法 ,这样的接口就成为函数式接口。 

在可以使用lambda表达式的地方,方法声明时必须包含一个函数式的接口。 

(JAVA8的接口可以有多个default方法)

任何函数式接口都可以使用lambda表达式替换。 

例如:ActionListener、Comparator、Runnable

lambda表达式只能出现在目标类型为函数式接口的上下文中。

注意: 

此处是只能!!! 

意味着如果我们提供的这个接口包含一个以上的Abstract Method,那么使用lambda表达式则会报错。 

这点已经验证过了。

场景: 

这种场景其实很常见: 

你在某处就真的只需要一个能做一件事情的函数而已,连它叫什么名字都无关紧要。 

Lambda 表达式就可以用来做这件事。


六.写法、规则

基本语法: 

(parameters) -> expression 或 (parameters) ->{ statements; } 

即: 参数 -> 带返回值的表达式/无返回值的陈述
<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.</span> 接收<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>个int型整数,返回他们的和
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(int x, int y)</span> -></span> x + y;

<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2.</span> 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回<span class="hljs-reserved" style="box-sizing: border-box;">void</span>)
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(String s)</span> -></span> System.out.<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(s);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>


七.几个特性

1. 类型推导 

编译器负责推导lambda表达式的类型。它利用lambda表达式所在上下文所期待的类型进行推导, 

这个被期待的类型被称为目标类型。就是说我们传入的参数可以无需写类型了!

2.变量捕获 

在Java SE 7中,编译器对内部类中引用的外部变量(即捕获的变量)要求非常严格: 

如果捕获的变量没有被声明为final就会产生一个编译错误。 

我们现在放宽了这个限制——对于lambda表达式和内部类, 

我们允许在其中捕获那些符合有效只读(Effectively final)的局部变量。

简单的说,如果一个局部变量在初始化后从未被修改过,那么它就符合有效只读的要求, 

换句话说,加上final后也不会导致编译错误的局部变量就是有效只读变量。

注意:此处和final关键字一样,指的是引用不可改!(感觉没多大意义,还不是用的final)

3.方法引用 

如果我们想要调用的方法拥有一个名字,我们就可以通过它的名字直接调用它。 

Comparator byName = Comparator.comparing(Person::getName); 

此处无需再传入参数,lambda会自动装配成Person类型进来然后执行getName()方法,而后返回getName()的String

方法引用有很多种,它们的语法如下:

静态方法引用:ClassName::methodName 

实例上的实例方法引用:instanceReference::methodName 

超类上的实例方法引用:super::methodName 

类型上的实例方法引用:ClassName::methodName 

构造方法引用:Class::new 

数组构造方法引用:TypeName[]::new

4.JAVA提供给我们的SAM接口 

Java SE 8中增加了一个新的包:java.util.function,它里面包含了常用的函数式接口,例如:
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">Predicate<<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>>——接收<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>对象并返回boolean
Consumer<<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>>——接收<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>对象,不返回值
Function<<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>, R>——接收<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>对象,返回R对象
Supplier<<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>>——提供<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>对象(例如工厂),不接收值
UnaryOperator<<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>>——接收<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>对象,返回<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>对象
BinaryOperator<<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>>——接收两个<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>对象,返回<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">T</span>对象</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li></ul>


那么在参数为这些接口的地方,我们就可以直接使用lambda表达式了!


八.更多的例子

1.自定义SAM接口,从而使用lambda表达式
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.lambda.myaction;

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 自定义一个函数式接口
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> MingChenchen
*
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MyActionInterface</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">saySomeThing</span>(String str);
<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* Java8引入的新特性 接口中可以定义一个default方法的实现 (不是abstract)
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">default</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> say(){
System.out.println(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"default say"</span>);

}
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.lambda.myaction;

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 在我们自定义的函数式接口的地方使用lambda表达式
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> MingChenchen
*
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">WantSay</span> {</span>
<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 执行接口中的saySomeThing方法
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> action
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @param</span> thing
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">excuteSay</span>(MyActionInterface action,String thing){
action.saySomeThing(thing);
}

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*
excuteSay(new MyActionInterface(){
@Override
public void saySomeThing(String str) {
System.out.println(str);
}
},"Hello World");
*/</span>

excuteSay((String s) -> System.out.println(s),<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Hello world new"</span>);

}
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li></ul>


2.使用方法引用( ClassName::Method,无括号)
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">package</span> com.lambda.usebean;

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 实体类Person
*<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box;"> @author</span> MingChenchen
*
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Person</span> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String name;      <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//姓名</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> String location;  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//地址</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">getName</span>() {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> name;
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setName</span>(String name) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.name = name;
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">getLocation</span>() {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> location;
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">setLocation</span>(String location) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.location = location;
}

<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> String <span class="hljs-title" style="box-sizing: border-box;">toString</span>() {
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// TODO Auto-generated method stub</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Person:"</span> + name + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">","</span> + location;
}
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li></ul>
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用String默认的排序规则,比较的是Person的name字段</span>
Comparator<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>Person<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> byName <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> Comparator<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>comparing(p <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>p<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getName());
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//不用写传入参数,传入的用Person来声明</span>
Comparator<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span>Person<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> byName2 <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> Comparator<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>comparing(Person<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">::getName</span>);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>


3.使用lambda表达式完成for-each循环操作
<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//原本的for-each循环写做法</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">List</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">list</span> = Arrays.asList(....);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (int i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>; i < <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">list</span>.size(); i++) {
System.out.println(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">list</span>.get(i));
}

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用lambda表达式后的写法</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">list</span>.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">forEach</span>(str -> System.out.println(str));</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>


list.forEach()是JAVA8的新方法,支持函数式编程,此处使用的参数就是JAVA提供给我们的函数式接口:Consumer< T>
<code class="hljs axapta has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">List</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">E</span>> <span class="hljs-inheritance" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span></span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Collection</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">E</span>>
<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Collection</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">E</span>> <span class="hljs-inheritance" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span></span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Iterable</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">E</span>>

<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">public</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Iterable</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">T</span>> {</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">default</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> forEach(Consumer<? <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span> T> action) {
Objects.requireNonNull(action);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (T t : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>) {
action.accept(t);
}
}
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>


4.一个完整的例子
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">//普通写法:
List<Person> people = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span>
Collections.sort(people, new Comparator<Person>() {
public int compare(Person x, Person y) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> x.getLastName().compareTo(y.getLastName());
}
})

//使用lambda表达式写法:
people.sort(comparing(Person::getLastName));</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>


化简流程:
<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">第一步:去掉冗余的匿名类
Collections.sort<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(people,(Person x, Person y) -> x.getLastName().compareTo(y.getLastName()))</span>;

第二步:使用<span class="hljs-title" style="box-sizing: border-box;">Comparator</span>里的<span class="hljs-title" style="box-sizing: border-box;">comparing</span>方法
<span class="hljs-title" style="box-sizing: border-box;">Collections</span>.<span class="hljs-title" style="box-sizing: border-box;">sort</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(people, Comparator.comparing((Person p) -> p.getLastName()))</span>;

第三步:类型推导和静态导入
<span class="hljs-title" style="box-sizing: border-box;">Collections</span>.<span class="hljs-title" style="box-sizing: border-box;">sort</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(people, comparing(p -> p.getLastName()))</span>;

第四步:方法引用
<span class="hljs-title" style="box-sizing: border-box;">Collections</span>.<span class="hljs-title" style="box-sizing: border-box;">sort</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(people, comparing(Person::getLastName))</span>;

第五步:使用<span class="hljs-title" style="box-sizing: border-box;">List</span>本身的<span class="hljs-title" style="box-sizing: border-box;">sort</span>更优
<span class="hljs-title" style="box-sizing: border-box;">people</span>.<span class="hljs-title" style="box-sizing: border-box;">sort</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(comparing(Person::getLastName))</span>;;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li></ul>


九.优缺点

优点: 

1.极大的简化代码。去除了很多无用的Java代码,使得代码更为简洁明了。 

2.比匿名内部类更加高效(不确定)。编译器会生成专门的lambda方法,可以使用javap -p查看编译过后的代码

缺点: 

1.可读性差。在代码简洁的情况下,另一方面又让大多程序员很难读懂。因为很少程序员接触使用它。 

(不过这个缺点不是本身缺点,而且源于程序员较少使用)


十.它是一个语法糖吗?

答: 

就我自身的理解来说,lambda表达式不算是一个语法糖。 

语法糖就是说只是帮助我们程序员轻松的少写一些代码,之后编译器帮我们把那部分代码生成出来。 

但是从编译过后的结果来说,并不是自动帮我们生成一个内部匿名类,而是生成了一个lambda$X方法。 

第二个就是lambda其实表达的是目前流行的“函数式编程”这种思维。区别于我们面向对象的思维方法。 

这点我认为很有意义,即我们要从各种思维来对待事情。而不是说,面向对象的这种方法就是最NB的。

但是论坛基本都认为这是一个语法糖,也没错。毕竟它提倡的只是一种思想,而且jdk底层为lambda生成了新的高效的代码这个事儿并不确定。

接下来介绍 lambda的 好哥们:stream. 

stream的方法里面大多都使用了lambda表达式


stream概要


一.什么是stream?

官方解释:
<code class="hljs oxygene has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">A <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sequence</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">of</span> elements supporting sequential <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">and</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">parallel</span> aggregate operations.</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>


简单来讲,stream就是JAVA8提供给我们的对于元素集合统一、快速、并行操作的一种方式。 

它能充分运用多核的优势,以及配合lambda表达式、链式结构对集合等进行许多有用的操作。

概念: 

stream:可以支持顺序和并行对元素操作的元素集合。

作用: 

提供了一种操作大数据接口,让数据操作更容易和更快 

使用stream,我们能够对collection的元素进行过滤、映射、排序、去重等许多操作。

中间方法和终点方法: 

它具有过滤、映射以及减少遍历数等方法,这些方法分两种:中间方法和终端方法, 

“流”抽象天生就该是持续的,中间方法永远返回的是Stream,因此如果我们要获取最终结果的话, 

必须使用终点操作才能收集流产生的最终结果。区分这两个方法是看他的返回值, 

如果是Stream则是中间方法,否则是终点方法


二.如何使用stream?

1.通过Stream接口的静态工厂方法(注意:Java8里接口可以带静态方法); 

2.通过Collection接口的默认方法(默认方法:Default method,也是Java8中的一个新特性,就是接口中的一个带有实现的方法)–stream(),把一个Collection对象转换成Stream

一般情况下,我们都使用Collection接口的 .stream()方法得到stream.


三.常见的几个中间方法

中间方法即是一些列对元素进行的操作。譬如过滤、去重、截断等。

1.Filter(过滤)
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">//过滤<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">18</span>岁以上的人
List persons = …
Stream personsOver18 = persons<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.stream</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.filter</span>(p -> p<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getAge</span>() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">18</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">; </span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>


2.Map(对元素进行操作)
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//把person转成Adult</span>
Stream <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> persons<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>stream()<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>filter(p <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>p<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>getAge() <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">></span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">18</span>)<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">map</span>(person <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span><span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">new</span> Adult(person)); </code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


3.limit(截断) 

对一个Stream进行截断操作,获取其前N个元素,如果原Stream中包含的元素个数小于N,那就获取其所有的元素

4.distinct(去重) 

对于Stream中包含的元素进行去重操作(去重逻辑依赖元素的equals方法),新生成的Stream中没有重复的元素


四.常用的终点方法

通过中间方法,我们对stream的元素进行了统一的操作,但是中间方法得到还是一个stream。要想把它转换为新的集合、或者是统计等。我们需要使用终点方法。

1.count(统计) 

count方法是一个流的终点方法,可使流的结果最终统计,返回int,比如我们计算一下满足18岁的总人数
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">int countOfAdult=persons<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.stream</span>()
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.filter</span>(p -> p<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getAge</span>() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">18</span>)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.map</span>(person -> new Adult(person))
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.count</span>()<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>


2.Collect(收集流的结果) 

collect方法也是一个流的终点方法,可收集最终的结果
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">List adultList= persons<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.stream</span>()
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.filter</span>(p -> p<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getAge</span>() > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">18</span>)
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.map</span>(person -> new Adult(person))
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.collect</span>(Collectors<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.toList</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>


五.顺序流和并行流

每个Stream都有两种模式:顺序执行和并行执行。
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">//顺序流:
List <Person> people = list<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getStream</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.collect</span>(Collectors<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.toList</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

//并行流:
List <Person> people = list<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.getStream</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parallel</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.collect</span>(Collectors<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.toList</span>())<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

//可以看出,要使用并行流,只需要<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.parallel</span>()即可</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="box-sizing: border-box; position: absolute; width: 105px; height: 60px; right: 30px; top: 5px; color: rgb(255, 255, 255); cursor: pointer; z-index: 2;"><a target=_blank target="_blank" style="color: rgb(255, 153, 0); box-sizing: border-box;"><img src="http://static.blog.csdn.net/images/save_snippets.png" style="border: none; box-sizing: border-box; max-width: 100%;" alt="" /></a></div>


顾名思义,当使用顺序方式去遍历时,每个item读完后再读下一个item。

而使用并行去遍历时,数组会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。

并行流原理: 

List originalList = someData; 

split1 = originalList(0, mid);//将数据分小部分 

split2 = originalList(mid,end); 

new Runnable(split1.process());//小部分执行操作 

new Runnable(split2.process()); 

List revisedList = split1 + split2;//将结果合并

性能:如果是多核机器,理论上并行流则会比顺序流快上一倍。

以下是借用他人的一个测试两者性能的Demo.
<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">package com.lambda.stream;

import java.util.stream.IntStream;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> TestPerformance {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">main</span>(String[] args) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> t0 = System.nanoTime();

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//初始化一个范围100万整数流,求能被2整除的数字,toArray()是终点方法</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> a[]=IntStream.range(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>_000_000).filter(p -> p % <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>).toArray();

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> t1 = System.nanoTime();

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//和上面功能一样,这里是用并行流来计算</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> b[]=IntStream.range(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>_000_000).parallel().filter(p -> p % <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>).toArray();

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> t2 = System.nanoTime();

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//我本机的结果是serial: 0.06s, parallel 0.02s,证明并行流确实比顺序流快</span>

System.<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">out</span>.printf(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"serial: %.2fs, parallel %.2fs%n"</span>, (t1 - t0) * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1e-9</span>, (t2 - t1) * <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1e-9</span>);

}
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>


运行结果:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-label" style="box-sizing: border-box;">serial:</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.07</span>s
parallel <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.02</span>s</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>


可以看出,并行流的效率确实提高了3.5倍(我本机是4核,电脑较差.)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: