網上介紹java8新特性的概念已經很多了,我就不過多說了;
直接教你怎麼使用:
一.配置環境:
1.在工作空間的build.gradle中配置
buildscript {
repositories {
.....
// Java8 環境的搭建,所使用的配置
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
// Java8 環境的搭建,所使用的配置
classpath 'me.tatarka:gradle-retrolambda:3.3.1'
}
}
allprojects {
repositories {
.....
// Java8 環境的搭建,所使用的配置
mavenCentral()
}
}
2.在app/build.gradle中配置
// Java8 環境的搭建, 所使用的配置apply plugin: 'me.tatarka.retrolambda'android {....// Java8 環境的搭建, 所使用的配置compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}}
下面緊接說一下Lambda式的使用(其中一個特性)
概念:java1.8及以上版本才有的新特性.是一種新的文法
使用Lambda表達式要求:1.java為1.8及以上版本 2. 替換省略的代碼必須是接口,且接口内隻有一個方法.
http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650822789&idx=1&sn=aabf8b95e233a6bb19466e58fb90f812&chksm=80b78c1bb7c0050da725cb947e0ae3a657e74dbae210bd3228eeaa1f7a990e466bc31b25c0d0&mpshare=1&scene=23&srcid=0503IEuy3RzY0ycsMHxwAy9l#rd
Android使用Lambda,要先搭建環境 ( 注意資源在國外 , 要翻牆 ) :android studio 2.1及版本以上 https://github.com/evant/gradle-retrolambda
使用Lambda表達式,對傳統的代碼進行修改,分為調用系統的,調用自己的,無參,有參,多參等:
A.這段傳統寫法的代碼,真正有用的是run方法,而new Runnable()這件事,就顯得好無意義.
newThread(//匿名内部類,主要用到的就是run方法newRunnable() {@Overridepublic voidrun() {Log.d("PY","使用系統原生的代碼");}}) {}.start();//A.将上面的代碼替換成Lambda表達式(Runnable()變成灰色)//A.實際就是把沒有什麼作用的格式用 "()->" 替換,隻保留有作用的核心代碼.newThread(() -> Log.d("PY", "使用系統原生的代碼")) {}.start();
1.自定義一個類,定義一個方法,接收一個接口,執行裡面的方法
class MyButton {
public void setMyListener(MyListener myListener) {
//接口對象調用接口唯一的一個抽象方法,如果沒有調用參數就是灰色的
myListener.onStateChanged();
}
}
1.定義一個接口,内部有且隻能有一個抽象方法
interface MyListener {
//自定義一個接口,無參
void onStateChanged();
}
使用我們自定義的格式換成Lambda表達式,接口方法無參
MyButton myButton = newMyButton();myButton.setMyListener(newMyListener() {@Overridepublic voidonStateChanged() {Log.d("PY","使用自己定義的代碼");}});//B.使用Lambda表達式,() ->代表了上面的new MyListener() {void onStateChanged()...的代碼myButton.setMyListener(() -> Log.d("PY", "使用自己定義的代碼"));
2.自定義一個類,定義一個方法,接收一個接口,執行裡面的方法
class MyButton {
String s;
public MyButton(String s) {
this.s = s;
}
2.定義一個接口,内部有且隻能有一個抽象方法public void setMyListener(MyListener myListener) {
myListener.onStateChanged(s);
}
}
interfaceMyListener {//自定義一個接口,有參void onStateChanged(String s);}
使用我們自定義的格式換成Lambda表達式,接口方法有參
MyButton myButton = new MyButton("岩");myButton.setMyListener(new MyListener() {@Overridepublic void onStateChanged(String s) {Log.d("PY",s+"使用自己定義的代碼");}});
//B.使用Lambda表達式,第一種最常見,下面兩種雖然更簡化,但閱讀性不好,一般我們不用,了解即可myButton.setMyListener((String s)->Log.d("PY", s+"使用自己定義的代碼"));myButton.setMyListener((s)->Log.d("PY", s+"使用自己定義的代碼"));//這種寫法,隻能是接口方法的參數是一個,如果有多個的話,就不可以了myButton.setMyListener(s ->Log.d("PY", s+"使用自己定義的代碼"));
3.自定義一個類,定義一個方法,接收一個接口,執行裡面的方法
class MyButton {
String s;
int i;
public MyButton(String s, int i) {
this.s = s;
this.i = i;
}
3.定義一個接口,内部有且隻能有一個抽象方法public void setMyListener(MyListener myListener) {
//接口對象調用接口唯一的一個抽象方法
myListener.onStateChanged(s,i);
}
}
interfaceMyListener {
//自定義一個接口,有多個參數void onStateChanged(s,i);
}
用我們自定義的格式換成Lambda表達式,接口方法有多個參數
MyButton myButton =new MyButton("岩", 9);myButton.setMyListener(newMyListener() {
@Overridepublic voidonStateChanged(String s,int i) {System.out.println(s + "有"+i+"個老婆");}
});//B.使用Lambda表達式,注意:這裡不是一行代碼,而是多行,那麼就要加{}myButton.setMyListener((String s, int i) -> { System.out.println("岩富可敵國,是以有衆多的追求者"); System.out.println(s + "有"+i+"個老婆"); } );
4.自定義一個類,定義一個方法,接收一個接口,執行裡面的方法
class MyButton {
String s;
int i;
public MyButton(String s, int i) {
this.s = s;
this.i = i;
}
4.定義一個接口,内部有且隻能有一個抽象方法public void setMyListener(MyListener myListener) {
//接口對象調用接口唯一的一個抽象方法
myListener.onStateChanged(s,i);
}
}
interface MyListener {
//自定義一個接口,有多個參數boolean onStateChanged(s,i);
}
使用我們自定義的格式換成Lambda表達式,接口方法有多個參數且還有傳回值
MyButton myButton = new MyButton("岩", 9);
myButton.setMyListener(new MyListener() {
@Override
public boolean onStateChanged(String s, int i) {
System.out.println(s + "有"+i+"個老婆");
return false;
}
});
//B.使用Lambda表達式 注意:這裡就有了個return
myButton.setMyListener((String s, int i)->{
System.out.println(s + "有"+i+"個老婆");
return false;
}
);
* 注意:這裡自定義的接口,若沒用接口對象調用,那麼即便覆寫了其方法,也不會執行,沒有效果
* http://blog.csdn.net/whatfizzer/article/details/46992149
使用前提:符合Lambda表達式,首先要是Lambda, Lambda方法引用:一般我們不會去寫,但是第三方庫會用,看懂即可.非重點 提示:參數和傳回值必須和接口的唯一抽象方法保持一緻
private voidLambdaStaticMethod() {MyButton myButton =new MyButton("岩",9);myButton.setMyListener(newMyListener() {
@Overridepublic booleanonStateChanged(String s, inti) {
System.out.println(s +"有"+i+"個老婆");return false;
}
});//使用Lambda表達式的靜态方法引用,myButton.setMyListener(MainActivity :: ycf);} public static boolean ycf(String s, int i){System.out.println("我是Lambda的靜态方法引用");return false;}
靜态方法引用格式: 類名 :: 方法名 例子 ClassName :: MethodName 執行個體方法引用: 類對象 :: 方法名 例子 instanceReference :: MethodName
類型方法引用: 類名 :: 方法名 例子 ClassName :: MethodName 構造方法引用:Class :: new 二·Stream:
Stream是進階疊代器,以流的方式使用集合,數組以及其他資料結構,可以對資料進行各種運算(轉換,過濾等)
注意:Android中Stream隻能在單元測試裡運作
使用Stream的基本步驟:建立Stream ; 轉換Stream , 每次轉換原有Stream對象不改變,傳回一個新的Stream對象(可以有多次轉換);對Stream進行聚合操作,擷取想要的結果
學習Stream的作用:
第一:一般情況你的履歷:紮實的Java基礎與面向對象思想,掌握Java8的新特性. 第二:rxJava又叫響應式程式設計 : 觀察者模式 ,Lambda表達式, 使用Stream特性操作集合,進行異步加載
使用Stream過濾集合資料的步驟:
1.将集合轉換為Stream流 2.對Stream進行資料篩選 3.輸出篩選出來的資料
@TargetApi(Build.VERSION_CODES.N)
public static voidstreamFilter() {
//建立集合對象,塞入資料List<Integer> integers = Arrays.asList(1,2,3,4,5);//通過for循環,對集合的資料進行操作for(intx = 0; x < integers.size(); x++) {
//需求,隻要集合中的偶數,傳統的做法就比較麻煩了// System.out.println(integers.get(x));
}//使用java1.8的新特性Stream,把資料源變成流,報錯,按住alt+回車,選第二個.java.util.stream.Stream<Integer> stream = integers.stream();//隻要集合中的偶數,内部有接口,傳回值還是流stream.filter(newPredicate<Integer>() {
@Overridepublic booleantest(Integer integer) {
//參數integer就是不斷的代表集合中的一個資料,對資料進行篩選擷取,true就代表了這個資料被選中//對數除以2,餘數是否為0;returninteger % 2== 0;
}
})
//forEach和for循環一樣,将流資料轉化成對應集合類型資料進行輸出,隻不過輸出的資料是集合中符合條件的資料.forEach(newConsumer<Integer>() {
@Overridepublic voidaccept(Integer integer) {
System.out.println(integer);
}
});
//使用lambada表達式,對上面的代碼進行優化,這裡的最終運作,我就在測試類調用
}
使用Stream轉換集合資料,把原來集合中的資料類型,轉換為新的資料類型 :
1.将集合資料轉換為Stream流 2.對Stream進行資料轉換 3.輸出篩選出來的資料
@TargetApi(Build.VERSION_CODES.N) public static voidstreamMap() {
//建立集合對象,塞入資料List<Integer> integers = Arrays.asList(1,2,3,4,5);integers.stream()//轉換資料,參數 1.原有的參數類型對象 2.要轉換的參數類型對象.map(newFunction<Integer, String>() {
@OverridepublicString apply(Integer integer) {returninteger.toString();}
}).forEach(newConsumer<String>() {
@Overridepublic voidaccept(String s) {System.out.println(s);}
});
}