天天看點

JAVA8的新特性

網上介紹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_8
targetCompatibility 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() {
@Override
public 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() {
@Override
public 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;
     
          
}
          
public void setMyListener(MyListener myListener) {      
    myListener.onStateChanged(s);      
}      
}
          
2.定義一個接口,内部有且隻能有一個抽象方法
interfaceMyListener {
//自定義一個接口,有參
void onStateChanged(String s);
}

    使用我們自定義的格式換成Lambda表達式,接口方法有參

MyButton myButton = new MyButton("岩");
myButton.setMyListener(new MyListener() {
@Override
public 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;
           
}
          
public void setMyListener(MyListener myListener) {      
    //接口對象調用接口唯一的一個抽象方法      
    myListener.onStateChanged(s,i);      
}      
}
          
3.定義一個接口,内部有且隻能有一個抽象方法
interfaceMyListener {
//自定義一個接口,有多個參數
void onStateChanged(s,i);
}
用我們自定義的格式換成Lambda表達式,接口方法有多個參數
MyButton myButton =new MyButton("岩", 9);
myButton.setMyListener(newMyListener() {
@Override
public 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;
            
}
           
public void setMyListener(MyListener myListener) {      
    //接口對象調用接口唯一的一個抽象方法      
    myListener.onStateChanged(s,i);      
}      
}
           
4.定義一個接口,内部有且隻能有一個抽象方法
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() {
@Override
public 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>() {
@Override
public booleantest(Integer integer) {
//參數integer就是不斷的代表集合中的一個資料,對資料進行篩選擷取,true就代表了這個資料被選中
//對數除以2,餘數是否為0;
returninteger % 2== 0;
}
})
//forEach和for循環一樣,将流資料轉化成對應集合類型資料進行輸出,隻不過輸出的資料是集合中符合條件的資料
.forEach(newConsumer<Integer>() {
@Override
public 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>() {
@Override
publicString apply(Integer integer) {
    returninteger.toString();
}
})
.forEach(newConsumer<String>() {
@Override
public voidaccept(String s) {
    System.out.println(s);
}
});
}
JAVA8的新特性

繼續閱讀