標籤:function sys java 回調 介面 err 關係 匿名 日誌分析
一 .概述
集合是我們java程式員每天都需要的工具,沒有了集合,java程式員幾乎不能幹任何的事情,我們每天的工作也是在對集合進行不同的操作.
儘管集合的功能已經足夠強大,但是當我們面對複雜的業務問題的時候,利用原始的集合操作就會變得讓人噁心.
於是在java8之中出現了lambda和stream的API,為我們以一種更加優雅的方式使用集合.
沒錯,就是集合,當我們現在使用NOSQL,各種日誌分析,等等的大資料操作的時候,我們不可能使用原始的資料庫的sql操作協助我們完成如排序,求和,分組等操作了,
我們急缺一中工具來完成我們的任務,很讓人高興的一點就是,Stream做到了,並且很優雅.
那麼,函數式編程式編程和Stream,lambda有什麼關係呢? 就是因為java引入了函數式編程的編程範式來解決這個問題的,
因此,我們的起點就應該是函數式編程.
二 .從函數式編程到lambda
行為參數化,一個很抽象的概念,其實我們每天都在用,很像一種策略模式,如我們在js之中不斷傳入的回呼函數一樣.
在java8之中,函數式編程的根基就是lambda,這是整個java函數式編程的基礎.
在這裡不去說函數式編程的準確含義,因為沒有人能說清楚.
我們想在想做的就是引入lambda.
請看下面的例子:
我們以前使用線程Runnable的方式:
Runnable runnable = new Runnable() { @Override public void run() { for(;;) System.out.println("thread is running..."); } }; new Thread(runnable).start();
以前我們使用匿名內部類的方式來編寫一個Runnbale的實現,其實在上面的代碼之中,只有紅色部分是有用的.
當我們編寫了很多這樣的代碼之後,我們大概能夠知道,我們其實就是想建立一種行為而已(或者說一種實現而已),根本沒有必要每次都寫大量的模板代碼.
於是,在java8之中,我們可以寫下面的代碼.
new Thread(()->{ for(;;) System.out.println("thread is running..."); }).start();
嘿嘿,我們現在就編寫了一個lambda的運算式來描述我們的行為.
三 .lambda運算式的本質
lambda運算式的本質和匿名內部類是一樣的,而且它的條件更加苛刻.
下面的例子證明lambda和匿名內部類其實是一種事物:
Runnable run = ()->{ for(;;) System.out.println("thread is running..."); };
看到上面的代碼沒有編譯的問題了嗎? 這就證明lambda本質上就是一個匿名內部類的實現而已.
從這裡我們能夠看到,即使java出現了lambda,從本質上還是沒有推翻我們之前的世界觀.
在上面,提到了lambda的條件更加苛刻,為什麼呢?
我們知道,一個匿名內部類可以實現多個方法,但是lambda卻只能實現一個.
因此,在java8之中為了更好地表達lambda的使用,出現了一個新的概念,就是函數式介面.
看到了嗎,lambda和函數式介面出現了,函數式介面本身就是為了lambda服務的.
那麼,什麼是函數式介面呢?很簡單,就是一個介面(抽象類別)內部僅僅只有一個待實現的方法,我們就稱為函數式介面.
為了表達這個概念,在java8之中使用一個註解表達這個概念,
public @interface FunctionalInterface {}
這個註解僅僅只是一個標記註解,能提供的作用僅僅是在編譯之前指明語法錯誤,像@Override一樣.
即使一個介面沒有這個註解,也不會妨礙這個介面成為一個函數式介面.
001 java為什麼需要函數式編程