
Lambda,是不是聽著很熟悉,沒錯,在高等數學中這貨經常和我們打交道,哈哈,這是一個希臘字母了,排名第十一,大寫是Λ,小寫是λ。
好了,是這樣的。jdk1.8中新增的核心特性有lambda表達式,函數式接口,流API,默認方法,新的Date,以及Time API。
下面給大家介紹的是Lambda表達式,該表達式允許我們把行為傳到函數里。之前把行為傳到函數里我們采用的是匿名內部類,該方法導致行為最重要的方法夾雜在中間,不夠突出。
lambda表達式取代了匿名內部類,取消了模板,允許程序猿用函數式風格編寫代碼,使代碼可讀性更高,盡管剛開始你會看不懂,但是你應該嘗試,畢竟這是新的東西,我已從中獲益。
Lambda表達式是在JDK 8中開始支持的一種函數式推導語言, 能夠大量減少匿名內部類那種冗余的代碼。 在Android中, 可以大量使用在設置監聽, 設置異步回調等場景。
基本格式是:() -> {}
有下面三種具體表達:
(params) -> exPRession(params) -> statement(params) -> {statement}1.引入retrolambda插件:
as里的配置 要使用lambda,首先必須配置編譯環境,這里使用的android studio,as默認的jdk版本是1.6,修改成1.8即可使用,這里確保你系統安裝了jdk1.8,否則需要用到下面插件: gradle-retrolambda
一。 jdk8裝上二。在project 的build.gradle dependencies { classpath 'com.android.tools.build:gradle:2.0.0' classpath 'me.tatarka:gradle-retrolambda:3.2.5' }三。在android module 的build.gradleapply plugin: 'com.android.application'apply plugin: 'me.tatarka.retrolambda'android { //設置當前的jdk編譯版本 8 compileOptions { sourceCompatibility javaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 }設置項目結構 按快捷鍵Ctrl+Shift+Alt+S進入項目結構設置,把app的jdk版本修改成1.8,注意你需要填寫1.8,因為那個下拉菜單里沒有這一選項,如下:
這里采用的是第二種方法,然后項目自動同步。
同步后是會在build.gradle腳本下生成和上面一樣的東東: 
點擊按鈕觸發事件 傳統的點擊事件,應用匿名內部類:
Button button = (Button) findViewById(R.id.btn_insert); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_LONG).show(); } });通過上面設置jdk版本為1.8后,鼠標放到new View.OnClickListener()里會有下面 然后我們按快捷鍵Alt+Enter,是這樣的
Button button = (Button) findViewById(R.id.btn_insert);button.setOnClickListener(v -> Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_LONG).show());一行代碼就搞定了,清晰可見,把行為傳到了函數里,這里注意v不可省略,是函數onClick的參數,當然就可以是任意名字,我還是建議就用一個字母表示,簡單嘛,當然了首先你得知道她的意思,盡管她的很多行為你始終不會明白
實現Runnable接口 傳統實現Runnable接口是這樣的:
new Thread(new Runnable() { @Override public void run() { Log.i("TAG", "haha"); }}).start();使用lambda表達式之后是這樣的:
new Thread(() -> { Log.i("TAG", "haha");}).start();
栗子
private void case2() {//2.2.按鈕點擊Button button = (Button) findViewById(R.id.btn);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(MainActivity.this, "點", Toast.LENGTH_SHORT).show();}});button.setOnClickListener((View v) ->Toast.makeText(MainActivity.this, "點", Toast.LENGTH_SHORT).show());}1。 方法引用是什么? 是lambda表達式的一個簡化寫法. 方法引用語法:左邊是容器( 可以是類名, 實例名) , 中間是” :: “, 右邊是相應的方法名。 如下
一般方法的引用格式是 如果是靜態方法, 則是ClassName::methodName。 如 Object ::equals 如果是實例方法, 則是Instance::methodName。 如Object obj=new Object();obj::equals; 構造函數.則是ClassName::new
//這里setOnClickListener方法的參數是OnClickListener, 是一個函數式接口//使用lambda表達式方式button1.setOnClickListener(v -> { System.out.println("這里是Lambda實現方式"); });//使用方法引用方式button2.setOnClickListener(TestMethodReference::doSomething);} public static void doSomething(ActionEvent e) {System.out.println("這里是方法引用實現方式");}private void case3() {//2.3.雙冒號:: 更簡化的lambda表達式Button button = (Button) findViewById(R.id.btn);//button.setOnClickListener(Cat::toast);//調用靜態方法的例子 要求toast的參數與OnClickListner一致//Cat cat=new Cat();//button.setOnClickListener(cat::toast2);//調用成員方法的例子 要求toast2的參數與OnClickListner一致button.setOnClickListener(Cat::new);//調用構造方法方法的例子 要求構造方法的參數與OnClickListner一致}既然lambda表達式即將正式取代Java代碼中的匿名內部類,那么有必要對二者做一個比較分析。
第一個關鍵的不同點就是關鍵字 this。匿名類的 this 關鍵字指向匿名類,而lambda表達式的 this 關鍵字指向包圍lambda表達式的類。
第二是編譯方式。Java編譯器將lambda表達式編譯成類的私有方法。使用了Java 7的 invokedynamic 字節碼指令來動態綁定這個方法。
什么是泛型 泛型是Java SE 1.5的新特性, 通俗點將就是“類型的變量”。 這種類型變量可以用在類、 接口和方法的創建中。
List<Apple> box = new ArrayList<Apple>();box.add(new Apple());Apple apple =box.get(0);如果沒有泛型就可需要類型轉換
Apple apple = (Apple)box.get(0);什么是自動推斷 java7的泛型類型推斷改進:為了減少泛型的代碼長度。 例如: Jdk7之前
Map<String, String> myMap = new HashMap<String, String>();而使用jdk7自動推斷之后:
Map<String, String> myMap = new HashMap<>(); //注意后面的"<>"為什么可以這樣做? 聲明變量的的時候已經指明了參數類型, 所以就不需要在初始化對象時再指定? 看到這點:JDK7新增了根據聲明變量獲取參數類型的這一特性就叫 自動推斷 . Java8的泛型類型推斷改進
//通過方法賦值的目標參數來自動推斷泛型的類型List<String> l = List.nil();//而不是顯示的指定類型//List<String> l = List.<String>nil();//通過前面方法參數類型推斷泛型的類型List.cons(42, List.nil());//而不是顯示的指定類型//List.cons(42, List.<Integer>nil());1。 外部VS forEach 內部迭代 以前Java集合是不能夠表達內部迭代的, 而只提供了一種外部迭代的方式, 也就是for或者while循環。 jdk8之前
List persons = asList(new Person("Joe"), new Person("Jim"), new Person("John"));for (Person p : persons) {p.setLastName("Doe");}jdk8 用lambda和Collection.forEach重寫上面的循環
persons.forEach(p->p.setLastName("Doe"));新聞熱點
疑難解答